diff --git a/CMakeLists.txt b/CMakeLists.txt
index a28c613..645a1a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@
 option (DISABLE_IPMB "Disable installing IPMB sensor" OFF)
 option (DISABLE_MCUTEMP "Disable installing MCU temperature sensor" OFF)
 option (DISABLE_PSU "Disable installing PSU sensor" OFF)
+option (DISABLE_NVME "Disable installing NVME sensor" ON)
 
 include ("cmake/HunterGate.cmake")
 
@@ -74,10 +75,13 @@
 set (PSU_SRC_FILES src/Utils.cpp src/PSUSensor.cpp src/Thresholds.cpp
      src/PwmSensor.cpp src/PSUEvent.cpp)
 
+set (NVME_SRC_FILES src/Utils.cpp src/NVMeSensorMain.cpp src/NVMeSensor.cpp src/Thresholds.cpp)
+
 set (EXTERNAL_PACKAGES Boost sdbusplus-project nlohmann-json)
 set (SENSOR_LINK_LIBS -lsystemd stdc++fs sdbusplus)
 
 if (NOT YOCTO)
+    set (DISABLE_NVME ON) # todo allow this to build out of tree
     option (ENABLE_TEST "Enable Google Test" OFF)
 
     externalproject_add (
@@ -112,6 +116,7 @@
                          CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND
                          "" LOG_DOWNLOAD ON)
     include_directories (SYSTEM ${CMAKE_BINARY_DIR}/nlohmann-json-src/include)
+
     if (ENABLE_TEST)
         option (HUNTER_ENABLED "Enable hunter package pulling" ON)
         hunter_add_package (GTest)
@@ -190,6 +195,12 @@
 add_dependencies (psusensor sdbusplus-project)
 target_link_libraries (psusensor ${SENSOR_LINK_LIBS})
 
+if (NOT DISABLE_NVME)
+    add_executable (nvmesensor ${NVME_SRC_FILES})
+    add_dependencies (nvmesensor sdbusplus-project)
+    target_link_libraries (nvmesensor liblibmctp.a i2c ${SENSOR_LINK_LIBS})
+endif()
+
 if (NOT YOCTO)
     add_dependencies (adcsensor ${EXTERNAL_PACKAGES})
     add_dependencies (cpusensor ${EXTERNAL_PACKAGES})
@@ -273,3 +284,10 @@
                  ${SERVICE_FILE_SRC_DIR}/xyz.openbmc_project.psusensor.service
                  DESTINATION ${SERVICE_FILE_INSTALL_DIR})
 endif ()
+
+if (NOT DISABLE_NVME)
+    install (TARGETS nvmesensor DESTINATION bin)
+    install (FILES
+                 ${SERVICE_FILE_SRC_DIR}/xyz.openbmc_project.nvmesensor.service
+                 DESTINATION ${SERVICE_FILE_INSTALL_DIR})
+endif ()
diff --git a/include/NVMeDevice.hpp b/include/NVMeDevice.hpp
new file mode 100644
index 0000000..5ebb0b3
--- /dev/null
+++ b/include/NVMeDevice.hpp
@@ -0,0 +1,99 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdlib.h>
+
+// NVM Express Management Interface 1.0 section 3.2.1
+const uint8_t NVME_MI_MESSAGE_TYPE = 0x04;
+
+const uint8_t NVME_MI_MESSAGE_TYPE_MASK = 0x7F;
+
+// Indicates this is covered by an MCTP integrity check
+const uint8_t NVME_MI_MCTP_INTEGRITY_CHECK = (1 << 7);
+
+// Indicates whether this is a request or response
+const uint8_t NVME_MI_HDR_FLAG_ROR = (1 << 7);
+
+const uint8_t NVME_MI_HDR_FLAG_MSG_TYPE_MASK = 0x0F;
+const uint8_t NVME_MI_HDR_FLAG_MSG_TYPE_SHIFT = 3;
+
+const uint16_t NVME_MI_MSG_BUFFER_SIZE = 256;
+
+// Minimum length of health status poll response
+// NMH + Status + NVMe-MI Command Response Message (NCRESP)
+const uint8_t NVME_MI_HEALTH_STATUS_POLL_MSG_MIN = 8;
+
+enum NVME_MI_HDR_MESSAGE_TYPE
+{
+    NVME_MI_HDR_MESSAGE_TYPE_CONTROL_PRIMITIVE = 0x00,
+    NVME_MI_HDR_MESSAGE_TYPE_MI_COMMAND = 0x01,
+    NVME_MI_HDR_MESSAGE_TYPE_MI_ADMIN_COMMAND = 0x02,
+    NVME_MI_HDR_MESSAGE_TYPE_PCIE_COMMAND = 0x04,
+};
+
+enum NVME_MI_HDR_COMMAND_SLOT
+{
+    NVME_MI_HDR_COMMAND_SLOT_0 = 0x00,
+    NVME_MI_HDR_COMMAND_SLOT_1 = 0x01,
+};
+
+enum NVME_MI_HDR_STATUS
+{
+    NVME_MI_HDR_STATUS_SUCCESS = 0x00,
+    NVME_MI_HDR_STATUS_MORE_PROCESSING_REQUIRED = 0x01,
+    NVME_MI_HDR_STATUS_INTERNAL_ERROR = 0x02,
+    NVME_MI_HDR_STATUS_INVALID_COMMAND_OPCODE = 0x03,
+    NVME_MI_HDR_STATUS_INVALID_PARAMETER = 0x04,
+    NVME_MI_HDR_STATUS_INVALID_COMMAND_SIZE = 0x05,
+    NVME_MI_HDR_STATUS_INVALID_COMMAND_INPUT_DATA_SIZE = 0x06,
+    NVME_MI_HDR_STATUS_ACCESS_DENIED = 0x07,
+    NVME_MI_HDR_STATUS_VPD_UPDATES_EXCEEDED = 0x20,
+    NVME_MI_HDR_STATUS_PCIE_INACCESSIBLE = 0x21,
+};
+
+enum NVME_MI_OPCODE
+{
+    NVME_MI_OPCODE_READ_MI_DATA = 0x00,
+    NVME_MI_OPCODE_HEALTH_STATUS_POLL = 0x01,
+    NVME_MI_OPCODE_CONTROLLER_HEALTH_STATUS_POLL = 0x02,
+    NVME_MI_OPCODE_CONFIGURATION_GET = 0x03,
+    NVME_MI_OPCODE_CONFIGURATION_SET = 0x04,
+    NVME_MI_OPCODE_VPD_READ = 0x05,
+    NVME_MI_OPCODE_VPD_WRITE = 0x06,
+    NVME_MI_OPCODE_RESET = 0x07,
+};
+
+const uint8_t NVME_MI_MSG_REQUEST_HEADER_SIZE = 16;
+struct nvme_mi_msg_request_header
+{
+    uint8_t message_type;
+    uint8_t flags;
+    uint8_t opcode;
+    uint32_t dword0;
+    uint32_t dword1;
+};
+
+struct nvme_mi_msg_request
+{
+    struct nvme_mi_msg_request_header header;
+    uint8_t request_data[128];
+    size_t request_data_len;
+};
+
+const uint8_t NVME_MI_MSG_RESPONSE_HEADER_SIZE = 5;
+struct nvme_mi_msg_response_header
+{
+    uint8_t message_type;
+    uint8_t flags;
+    // Reserved bytes 2:3
+    uint8_t status;
+};
+
+struct nvme_mi_controller_health
+{
+    uint8_t nvm_subsystem_status;
+    uint8_t smart_warnings;
+    uint8_t composite_temperature;
+    uint8_t percent_used;
+    uint16_t composite_controller_status;
+};
\ No newline at end of file
diff --git a/include/NVMeSensor.hpp b/include/NVMeSensor.hpp
new file mode 100644
index 0000000..ec0bfd1
--- /dev/null
+++ b/include/NVMeSensor.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <libmctp-smbus.h>
+#include <libmctp.h>
+
+#include <sensor.hpp>
+
+class NVMeSensor : public Sensor
+{
+  public:
+    NVMeSensor(sdbusplus::asio::object_server& objectServer,
+               boost::asio::io_service& io,
+               std::shared_ptr<sdbusplus::asio::connection>& conn,
+               const std::string& sensorName,
+               std::vector<thresholds::Threshold>&& _thresholds,
+               const std::string& sensorConfiguration, const int busNumber);
+    virtual ~NVMeSensor();
+
+    NVMeSensor& operator=(const NVMeSensor& other) = delete;
+
+    size_t errorCount;
+    int bus;
+
+  private:
+    sdbusplus::asio::object_server& objServer;
+
+    void checkThresholds(void) override;
+};
+
+struct NVMeContext : std::enable_shared_from_this<NVMeContext>
+{
+    NVMeContext(boost::asio::io_service& io, int rootBus);
+
+    virtual ~NVMeContext();
+
+    void pollNVMeDevices();
+
+    boost::asio::deadline_timer scanTimer;
+    int rootBus; // Root bus for this drive
+    boost::asio::deadline_timer mctpResponseTimer;
+    boost::asio::ip::tcp::socket nvmeSlaveSocket;
+    std::list<std::shared_ptr<NVMeSensor>> sensors; // used as a poll queue
+};
+
+using NVMEMap = boost::container::flat_map<int, std::shared_ptr<NVMeContext>>;
+
+int verifyIntegrity(uint8_t* msg, size_t len);
+
+namespace nvmeMCTP
+{
+void init(void);
+}
+
+NVMEMap& getNVMEMap(void);
diff --git a/service_files/xyz.openbmc_project.nvmesensor.service b/service_files/xyz.openbmc_project.nvmesensor.service
new file mode 100644
index 0000000..a5c8725
--- /dev/null
+++ b/service_files/xyz.openbmc_project.nvmesensor.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=NVMe Sensor
+StopWhenUnneeded=false
+After=xyz.openbmc_project.FruDevice.service
+
+[Service]
+Restart=always
+RestartSec=5
+ExecStart=/usr/bin/nvmesensor
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/src/NVMeSensor.cpp b/src/NVMeSensor.cpp
new file mode 100644
index 0000000..be99f58
--- /dev/null
+++ b/src/NVMeSensor.cpp
@@ -0,0 +1,478 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "NVMeSensor.hpp"
+
+#include "NVMeDevice.hpp"
+
+#include <crc32c.h>
+#include <libmctp-smbus.h>
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <iostream>
+
+static constexpr double maxReading = 127;
+static constexpr double minReading = 0;
+
+static constexpr bool DEBUG = false;
+
+void rxMessage(uint8_t eid, void* data, void* msg, size_t len);
+
+namespace nvmeMCTP
+{
+struct mctp_binding_smbus* smbus = mctp_smbus_init();
+struct mctp* mctp = mctp_init();
+
+static boost::container::flat_map<int, int> inFds;
+static boost::container::flat_map<int, int> outFds;
+
+int getInFd(int rootBus)
+{
+    auto findBus = inFds.find(rootBus);
+    if (findBus != inFds.end())
+    {
+        return findBus->second;
+    }
+    int fd = mctp_smbus_open_in_bus(smbus, rootBus);
+    if (fd < 0)
+    {
+        std::cerr << "Error opening IN Bus " << rootBus << "\n";
+    }
+    inFds[rootBus] = fd;
+    return fd;
+}
+
+int getOutFd(int bus)
+{
+    auto findBus = outFds.find(bus);
+    if (findBus != outFds.end())
+    {
+        return findBus->second;
+    }
+    int fd = mctp_smbus_open_out_bus(smbus, bus);
+    if (fd < 0)
+    {
+        std::cerr << "Error opening Out Bus " << bus << "\n";
+    }
+    outFds[bus] = fd;
+    return fd;
+}
+
+// we don't close the outFd as multiple sensors could be sharing the fd, we need
+// to close the inFd as it can only be used on 1 socket at a time
+void closeInFd(int rootBus)
+{
+    auto findFd = inFds.find(rootBus);
+    if (findFd == inFds.end())
+    {
+        return;
+    }
+    close(findFd->second);
+    inFds.erase(rootBus);
+}
+
+int getRootBus(int inFd)
+{
+    // we assume that we won't have too many FDs, so looping is OK
+    for (const auto [root, fd] : inFds)
+    {
+        if (fd == inFd)
+        {
+            return root;
+        }
+    }
+
+    return -1;
+}
+
+void init()
+{
+    if (mctp == nullptr || smbus == nullptr)
+    {
+        throw std::runtime_error("Unable to init mctp");
+    }
+    mctp_smbus_register_bus(smbus, nvmeMCTP::mctp, 0);
+    mctp_set_rx_all(mctp, rxMessage, nullptr);
+}
+
+} // namespace nvmeMCTP
+
+static int lastQueriedDeviceIndex = -1;
+
+void readResponse(const std::shared_ptr<NVMeContext>& nvmeDevice)
+{
+    nvmeDevice->nvmeSlaveSocket.async_wait(
+        boost::asio::ip::tcp::socket::wait_error,
+        [nvmeDevice](const boost::system::error_code errorCode) {
+            if (errorCode)
+            {
+                return;
+            }
+
+            mctp_smbus_set_in_fd(nvmeMCTP::smbus,
+                                 nvmeMCTP::getInFd(nvmeDevice->rootBus));
+
+            // through libmctp this will invoke rxMessage
+            mctp_smbus_read(nvmeMCTP::smbus);
+        });
+}
+
+int nvmeMessageTransmit(mctp& mctp, nvme_mi_msg_request& req)
+{
+    std::array<uint8_t, NVME_MI_MSG_BUFFER_SIZE> messageBuf = {};
+
+    req.header.flags |= NVME_MI_HDR_MESSAGE_TYPE_MI_COMMAND
+                        << NVME_MI_HDR_FLAG_MSG_TYPE_SHIFT;
+    req.header.message_type =
+        NVME_MI_MESSAGE_TYPE | NVME_MI_MCTP_INTEGRITY_CHECK;
+
+    uint32_t integrity = 0;
+    size_t msgSize = NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len +
+                     sizeof(integrity);
+
+    if (sizeof(messageBuf) < msgSize)
+    {
+        return EXIT_FAILURE;
+    }
+
+    messageBuf[0] = req.header.message_type;
+    messageBuf[1] = req.header.flags;
+    // Reserved bytes 2-3
+
+    messageBuf[4] = req.header.opcode;
+    // reserved bytes 5-7
+    messageBuf[8] = req.header.dword0 & 0xff;
+    messageBuf[9] = (req.header.dword0 >> 8) & 0xff;
+    messageBuf[10] = (req.header.dword0 >> 16) & 0xff;
+    messageBuf[11] = (req.header.dword0 >> 24) & 0xff;
+
+    messageBuf[12] = req.header.dword1 & 0xff;
+    messageBuf[13] = (req.header.dword1 >> 8) & 0xff;
+    messageBuf[14] = (req.header.dword1 >> 16) & 0xff;
+    messageBuf[15] = (req.header.dword1 >> 24) & 0xff;
+
+    std::copy_n(req.request_data, req.request_data_len,
+                messageBuf.data() +
+                    static_cast<uint8_t>(NVME_MI_MSG_REQUEST_HEADER_SIZE));
+
+    msgSize = NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len;
+    integrity = crc32c(messageBuf.data(),
+                       NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len);
+    messageBuf[msgSize] = integrity & 0xff;
+    messageBuf[msgSize + 1] = (integrity >> 8) & 0xff;
+    messageBuf[msgSize + 2] = (integrity >> 16) & 0xff;
+    messageBuf[msgSize + 3] = (integrity >> 24) & 0xff;
+    msgSize += sizeof(integrity);
+
+    return mctp_message_tx(&mctp, 0, messageBuf.data(), msgSize);
+}
+
+int verifyIntegrity(uint8_t* msg, size_t len)
+{
+    uint32_t msgIntegrity = {0};
+    if (len < NVME_MI_MSG_RESPONSE_HEADER_SIZE + sizeof(msgIntegrity))
+    {
+        std::cerr << "Not enough bytes for nvme header and trailer\n";
+        return -1;
+    }
+
+    msgIntegrity = (msg[len - 4]) + (msg[len - 3] << 8) + (msg[len - 2] << 16) +
+                   (msg[len - 1] << 24);
+
+    uint32_t calculateIntegrity = crc32c(msg, len - sizeof(msgIntegrity));
+    if (msgIntegrity != calculateIntegrity)
+    {
+        std::cerr << "CRC mismatch. Got=" << msgIntegrity
+                  << " Expected=" << calculateIntegrity << "\n";
+        return -1;
+    }
+    return 0;
+}
+
+void readAndProcessNVMeSensor(const std::shared_ptr<NVMeContext>& nvmeDevice)
+{
+    struct nvme_mi_msg_request requestMsg = {};
+    requestMsg.header.opcode = NVME_MI_OPCODE_HEALTH_STATUS_POLL;
+    requestMsg.header.dword0 = 0;
+    requestMsg.header.dword1 = 0;
+
+    int mctpResponseTimeout = 1;
+
+    if (nvmeDevice->sensors.empty())
+    {
+        return;
+    }
+
+    std::shared_ptr<NVMeSensor>& sensor = nvmeDevice->sensors.front();
+
+    // setup the timeout timer
+    nvmeDevice->mctpResponseTimer.expires_from_now(
+        boost::posix_time::seconds(mctpResponseTimeout));
+
+    nvmeDevice->mctpResponseTimer.async_wait(
+        [sensor, nvmeDevice](const boost::system::error_code errorCode) {
+            constexpr const size_t errorThreshold = 5;
+            if (errorCode)
+            {
+                return;
+            }
+            if (sensor->errorCount < errorThreshold)
+            {
+                std::cerr << "MCTP timeout device " << sensor->name << "\n";
+                sensor->errorCount++;
+            }
+            else
+            {
+                sensor->updateValue(0);
+            }
+
+            // cycle it back
+            nvmeDevice->sensors.pop_front();
+            nvmeDevice->sensors.emplace_back(sensor);
+
+            nvmeDevice->nvmeSlaveSocket.cancel();
+        });
+
+    readResponse(nvmeDevice);
+
+    if (DEBUG)
+    {
+        std::cout << "Sending message to read data from Drive on bus: "
+                  << sensor->bus << " , rootBus: " << nvmeDevice->rootBus
+                  << " device: " << sensor->name << "\n";
+    }
+
+    mctp_smbus_set_out_fd(nvmeMCTP::smbus, nvmeMCTP::getOutFd(sensor->bus));
+    int rc = nvmeMessageTransmit(*nvmeMCTP::mctp, requestMsg);
+
+    if (rc != 0)
+    {
+        std::cerr << "Error sending request message to NVMe device\n";
+    }
+}
+
+static double getTemperatureReading(int8_t reading)
+{
+
+    if (reading == static_cast<int8_t>(0x80) ||
+        reading == static_cast<int8_t>(0x81))
+    {
+        // 0x80 = No temperature data or temperature data is more the 5 s
+        // old 0x81 = Temperature sensor failure
+        return maxReading;
+    }
+
+    return reading;
+}
+
+void rxMessage(uint8_t eid, void*, void* msg, size_t len)
+{
+    struct nvme_mi_msg_response_header header
+    {
+    };
+
+    int inFd = mctp_smbus_get_in_fd(nvmeMCTP::smbus);
+    int rootBus = nvmeMCTP::getRootBus(inFd);
+
+    NVMEMap& nvmeMap = getNVMEMap();
+    auto findMap = nvmeMap.find(rootBus);
+    if (findMap == nvmeMap.end())
+    {
+        std::cerr << "Unable to lookup root bus " << rootBus << "\n";
+        return;
+    }
+    std::shared_ptr<NVMeContext>& self = findMap->second;
+
+    if (msg == nullptr)
+    {
+        std::cerr << "Bad message received\n";
+        return;
+    }
+
+    if (len <= 0)
+    {
+        std::cerr << "Received message not long enough\n";
+        return;
+    }
+
+    if (DEBUG)
+    {
+        std::cout << "Eid from the received messaged: " << eid << "\n";
+    }
+
+    uint8_t* messageData = static_cast<uint8_t*>(msg);
+
+    if ((*messageData & NVME_MI_MESSAGE_TYPE_MASK) != NVME_MI_MESSAGE_TYPE)
+    {
+        std::cerr << "Got unknown type message_type="
+                  << (*messageData & NVME_MI_MESSAGE_TYPE_MASK) << "\n";
+        return;
+    }
+
+    if (len < NVME_MI_MSG_RESPONSE_HEADER_SIZE + sizeof(uint32_t))
+    {
+        std::cerr << "Not enough bytes for NVMe header and trailer\n";
+        return;
+    }
+
+    if (verifyIntegrity(messageData, len) != 0)
+    {
+        std::cerr << "Verification of message integrity failed\n";
+        return;
+    }
+
+    header.message_type = messageData[0];
+    header.flags = messageData[1];
+    header.status = messageData[4];
+
+    if (header.status == NVME_MI_HDR_STATUS_MORE_PROCESSING_REQUIRED)
+    {
+        return;
+    }
+
+    if (header.status != NVME_MI_HDR_STATUS_SUCCESS)
+    {
+        std::cerr << "Command failed with status= " << header.status << "\n";
+        return;
+    }
+
+    messageData += NVME_MI_MSG_RESPONSE_HEADER_SIZE;
+    size_t messageLength =
+        len - NVME_MI_MSG_RESPONSE_HEADER_SIZE - sizeof(uint32_t);
+    if (((header.flags >> NVME_MI_HDR_FLAG_MSG_TYPE_SHIFT) &
+         NVME_MI_HDR_FLAG_MSG_TYPE_MASK) != NVME_MI_HDR_MESSAGE_TYPE_MI_COMMAND)
+    {
+        std::cerr << "Not MI type comamnd\n";
+        return;
+    }
+
+    if (messageLength < NVME_MI_HEALTH_STATUS_POLL_MSG_MIN)
+    {
+        std::cerr << "Got improperly sized health status poll\n";
+        return;
+    }
+
+    std::shared_ptr<NVMeSensor> sensorInfo = self->sensors.front();
+    if (DEBUG)
+    {
+        std::cout << "Temperature Reading: "
+                  << getTemperatureReading(messageData[5])
+                  << " Celsius for device " << sensorInfo->name << "\n";
+    }
+
+    sensorInfo->updateValue(getTemperatureReading(messageData[5]));
+
+    if (DEBUG)
+    {
+        std::cout << "Cancelling the timer now\n";
+    }
+
+    // move to back of scan queue
+    self->sensors.pop_front();
+    self->sensors.emplace_back(sensorInfo);
+
+    self->mctpResponseTimer.cancel();
+}
+
+NVMeContext::NVMeContext(boost::asio::io_service& io, int rootBus) :
+    rootBus(rootBus), scanTimer(io), nvmeSlaveSocket(io), mctpResponseTimer(io)
+{
+    nvmeSlaveSocket.assign(boost::asio::ip::tcp::v4(),
+                           nvmeMCTP::getInFd(rootBus));
+}
+
+void NVMeContext::pollNVMeDevices()
+{
+    scanTimer.expires_from_now(boost::posix_time::seconds(1));
+    scanTimer.async_wait(
+        [self{shared_from_this()}](const boost::system::error_code errorCode) {
+            if (errorCode == boost::asio::error::operation_aborted)
+            {
+                return; // we're being canceled
+            }
+            else if (errorCode)
+            {
+                std::cerr << "Error:" << errorCode.message() << "\n";
+                return;
+            }
+            else
+            {
+                readAndProcessNVMeSensor(self);
+            }
+
+            self->pollNVMeDevices();
+        });
+}
+
+NVMeContext::~NVMeContext()
+{
+    scanTimer.cancel();
+    mctpResponseTimer.cancel();
+    nvmeSlaveSocket.cancel();
+    nvmeMCTP::closeInFd(rootBus);
+}
+
+NVMeSensor::NVMeSensor(sdbusplus::asio::object_server& objectServer,
+                       boost::asio::io_service& io,
+                       std::shared_ptr<sdbusplus::asio::connection>& conn,
+                       const std::string& sensorName,
+                       std::vector<thresholds::Threshold>&& _thresholds,
+                       const std::string& sensorConfiguration,
+                       const int busNumber) :
+    Sensor(boost::replace_all_copy(sensorName, " ", "_"),
+           std::move(_thresholds), sensorConfiguration,
+           "xyz.openbmc_project.Configuration.NVMe", maxReading, minReading),
+    objServer(objectServer), errorCount(0), bus(busNumber)
+{
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/temperature/" + name,
+        "xyz.openbmc_project.Sensor.Value");
+
+    if (thresholds::hasWarningInterface(thresholds))
+    {
+        thresholdInterfaceWarning = objectServer.add_interface(
+            "/xyz/openbmc_project/sensors/temperature/" + name,
+            "xyz.openbmc_project.Sensor.Threshold.Warning");
+    }
+    if (thresholds::hasCriticalInterface(thresholds))
+    {
+        thresholdInterfaceCritical = objectServer.add_interface(
+            "/xyz/openbmc_project/sensors/temperature/" + name,
+            "xyz.openbmc_project.Sensor.Threshold.Critical");
+    }
+    association = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/temperature/" + name,
+        association::interface);
+
+    setInitialProperties(conn);
+    // setup match
+    setupPowerMatch(conn);
+}
+
+NVMeSensor::~NVMeSensor()
+{
+    // close the input dev to cancel async operations
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(sensorInterface);
+    objServer.remove_interface(association);
+}
+
+void NVMeSensor::checkThresholds(void)
+{
+    thresholds::checkThresholds(this);
+}
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
new file mode 100644
index 0000000..1858ea9
--- /dev/null
+++ b/src/NVMeSensorMain.cpp
@@ -0,0 +1,181 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "NVMeSensor.hpp"
+
+#include <boost/asio/deadline_timer.hpp>
+#include <regex>
+
+static constexpr const char* sensorType =
+    "xyz.openbmc_project.Configuration.NVME1000";
+
+static NVMEMap nvmeDeviceMap;
+
+static constexpr bool DEBUG = false;
+
+NVMEMap& getNVMEMap()
+{
+    return nvmeDeviceMap;
+}
+
+void createSensors(boost::asio::io_service& io,
+                   sdbusplus::asio::object_server& objectServer,
+                   std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+{
+
+    auto getter = std::make_shared<GetSensorConfiguration>(
+        dbusConnection,
+        std::move([&io, &objectServer, &dbusConnection](
+                      const ManagedObjectType& sensorConfigurations) {
+            // todo: it'd be better to only update the ones we care about
+            nvmeDeviceMap.clear();
+
+            // iterate through all found configurations
+            for (const std::pair<sdbusplus::message::object_path, SensorData>&
+                     sensor : sensorConfigurations)
+            {
+                const SensorData& sensorData = sensor.second;
+                const std::string& interfacePath = sensor.first.str;
+                const std::pair<
+                    std::string,
+                    boost::container::flat_map<std::string, BasicVariantType>>*
+                    baseConfiguration = nullptr;
+
+                // find base configuration
+                auto sensorBase = sensor.second.find(sensorType);
+                if (sensorBase != sensor.second.end())
+                {
+                    baseConfiguration = &(*sensorBase);
+                }
+
+                if (baseConfiguration == nullptr)
+                {
+                    continue;
+                }
+                auto findBus = baseConfiguration->second.find("Bus");
+                if (findBus == baseConfiguration->second.end())
+                {
+                    continue;
+                }
+
+                unsigned int busNumber =
+                    std::visit(VariantToUnsignedIntVisitor(), findBus->second);
+
+                auto findSensorName = baseConfiguration->second.find("Name");
+                if (findSensorName == baseConfiguration->second.end())
+                {
+                    std::cerr << "could not determine configuration name for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+                std::string sensorName =
+                    std::get<std::string>(findSensorName->second);
+
+                std::vector<thresholds::Threshold> sensorThresholds;
+
+                if (!parseThresholdsFromConfig(sensorData, sensorThresholds))
+                {
+                    std::cerr << "error populating thresholds for "
+                              << sensorName << "\n";
+                }
+
+                int rootBus = busNumber;
+
+                std::string muxPath = "/sys/bus/i2c/devices/i2c-" +
+                                      std::to_string(busNumber) + "/mux_device";
+
+                if (std::filesystem::is_symlink(muxPath))
+                {
+                    std::string rootName =
+                        std::filesystem::read_symlink(muxPath).filename();
+                    size_t dash = rootName.find("-");
+                    if (dash == std::string::npos)
+                    {
+                        std::cerr << "Error finding root bus for " << rootName
+                                  << "\n";
+                        continue;
+                    }
+                    rootBus = std::stoi(rootName.substr(0, dash));
+                }
+
+                std::shared_ptr<NVMeContext> context;
+                auto findRoot = nvmeDeviceMap.find(rootBus);
+                if (findRoot != nvmeDeviceMap.end())
+                {
+                    context = findRoot->second;
+                }
+                else
+                {
+                    context = std::make_shared<NVMeContext>(io, rootBus);
+                    nvmeDeviceMap[rootBus] = context;
+                }
+
+                std::shared_ptr<NVMeSensor> sensorPtr =
+                    std::make_shared<NVMeSensor>(
+                        objectServer, io, dbusConnection, sensorName,
+                        std::move(sensorThresholds), interfacePath, busNumber);
+
+                context->sensors.emplace_back(sensorPtr);
+            }
+            for (const auto& [_, context] : nvmeDeviceMap)
+            {
+                context->pollNVMeDevices();
+            }
+        }));
+    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.NVMeSensor");
+    sdbusplus::asio::object_server objectServer(systemBus);
+    nvmeMCTP::init();
+
+    io.post([&]() { createSensors(io, objectServer, systemBus); });
+
+    boost::asio::deadline_timer filterTimer(io);
+    std::function<void(sdbusplus::message::message&)> eventHandler =
+        [&filterTimer, &io, &objectServer,
+         &systemBus](sdbusplus::message::message& message) {
+            // this implicitly cancels the timer
+            filterTimer.expires_from_now(boost::posix_time::seconds(1));
+
+            filterTimer.async_wait([&](const boost::system::error_code& ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    return; // we're being canceled
+                }
+                else if (ec)
+                {
+                    std::cerr << "Error: " << ec.message() << "\n";
+                    return;
+                }
+
+                createSensors(io, objectServer, systemBus);
+            });
+        };
+
+    sdbusplus::bus::match::match configMatch(
+        static_cast<sdbusplus::bus::bus&>(*systemBus),
+        "type='signal',member='PropertiesChanged',path_namespace='" +
+            std::string(inventoryPath) + "',arg0namespace='" +
+            std::string(sensorType) + "'",
+        eventHandler);
+
+    io.run();
+}
