diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 9a49738..aa25a44 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -22,6 +22,7 @@
 #include "../lib/roles.hpp"
 #include "../lib/service_root.hpp"
 #include "../lib/ethernet.hpp"
+#include "../lib/thermal.hpp"
 #include "../lib/chassis.hpp"
 #include "webserver_common.hpp"
 
@@ -48,6 +49,7 @@
     nodes.emplace_back(std::make_unique<SessionService>(app));
     nodes.emplace_back(std::make_unique<EthernetCollection>(app));
     nodes.emplace_back(std::make_unique<EthernetInterface>(app));
+    nodes.emplace_back(std::make_unique<Thermal>(app));
     nodes.emplace_back(std::make_unique<ManagerCollection>(app));
     nodes.emplace_back(std::make_unique<ChassisCollection>(app));
     nodes.emplace_back(std::make_unique<Chassis>(app));
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index 02a614b..9f3fb38 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -248,6 +248,8 @@
           // Create JSON copy based on Node::json, this is to avoid possible
           // race condition
           nlohmann::json json_response(Node::json);
+          json_response["Thermal"] = {
+              {"@odata.id", "/redfish/v1/Chassis/" + chassis_id + "/Thermal"}};
           // If success...
           if (success) {
             // prepare all the schema required fields.
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
new file mode 100644
index 0000000..c48512a
--- /dev/null
+++ b/redfish-core/lib/sensors.hpp
@@ -0,0 +1,424 @@
+/*
+// 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 <math.h>
+#include <dbus_singleton.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/range/algorithm/replace_copy_if.hpp>
+#include <boost/variant.hpp>
+#include <boost/variant/get.hpp>
+
+namespace redfish {
+
+constexpr const char* DBUS_SENSOR_PREFIX = "/xyz/openbmc_project/Sensors/";
+
+using GetSubTreeType = std::vector<
+    std::pair<std::string,
+              std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+
+using ManagedObjectsVectorType = std::vector<std::pair<
+    dbus::object_path,
+    boost::container::flat_map<
+        std::string,
+        boost::container::flat_map<dbus::string, dbus::dbus_variant>>>>;
+
+/**
+ * AsyncResp
+ * Gathers data needed for response processing after async calls are done
+ */
+class AsyncResp {
+ public:
+  AsyncResp(crow::response& response, const std::string& chassisId,
+            const std::initializer_list<const char*> types)
+      : chassisId(chassisId), res(response), types(types) {
+    res.json_value["@odata.id"] =
+        "/redfish/v1/Chassis/" + chassisId + "/Thermal";
+  }
+
+  ~AsyncResp() {
+    if (res.code != static_cast<int>(HttpRespCode::OK)) {
+      // Reset the json object to clear out any data that made it in before the
+      // error happened
+      // todo(ed) handle error condition with proper code
+      res.json_value = nlohmann::json::object();
+    }
+    res.end();
+  }
+  void setErrorStatus() {
+    res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+  }
+
+  std::string chassisId{};
+  crow::response& res;
+  const std::vector<const char*> types;
+};
+
+/**
+ * @brief Creates connections necessary for chassis sensors
+ * @param asyncResp Pointer to object holding response data
+ * @param sensorNames Sensors retrieved from chassis
+ * @param callback Callback for processing gathered connections
+ */
+template <typename Callback>
+void getConnections(const std::shared_ptr<AsyncResp>& asyncResp,
+                    const boost::container::flat_set<std::string>& sensorNames,
+                    Callback&& callback) {
+  CROW_LOG_DEBUG << "getConnections";
+  const std::string path = "/xyz/openbmc_project/Sensors";
+  const std::array<std::string, 1> interfaces = {
+      "xyz.openbmc_project.Sensor.Value"};
+  const dbus::endpoint object_mapper(
+      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
+      "xyz.openbmc_project.ObjectMapper", "GetSubTree");
+
+  // Response handler for parsing objects subtree
+  auto resp_handler = [ callback{std::move(callback)}, asyncResp, sensorNames ](
+      const boost::system::error_code ec, const GetSubTreeType& subtree) {
+    if (ec != 0) {
+      asyncResp->setErrorStatus();
+      CROW_LOG_ERROR << "Dbus error " << ec;
+      return;
+    }
+
+    CROW_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
+
+    // Make unique list of connections only for requested sensor types and
+    // found in the chassis
+    boost::container::flat_set<std::string> connections;
+    // Intrinsic to avoid malloc.  Most systems will have < 8 sensor producers
+    connections.reserve(8);
+
+    CROW_LOG_DEBUG << "sensorNames list cout: " << sensorNames.size();
+    for (const std::string& tsensor : sensorNames) {
+      CROW_LOG_DEBUG << "Sensor to find: " << tsensor;
+    }
+
+    for (const std::pair<
+             std::string,
+             std::vector<std::pair<std::string, std::vector<std::string>>>>&
+             object : subtree) {
+      for (const char* type : asyncResp->types) {
+        if (boost::starts_with(object.first, type)) {
+          auto lastPos = object.first.rfind('/');
+          if (lastPos != std::string::npos) {
+            std::string sensorName = object.first.substr(lastPos + 1);
+
+            if (sensorNames.find(sensorName) != sensorNames.end()) {
+              // For each connection name
+              for (const std::pair<std::string, std::vector<std::string>>&
+                       objData : object.second) {
+                connections.insert(objData.first);
+              }
+            }
+          }
+          break;
+        }
+      }
+    }
+    CROW_LOG_DEBUG << "Found " << connections.size() << " connections";
+    callback(std::move(connections));
+  };
+
+  // Make call to ObjectMapper to find all sensors objects
+  crow::connections::system_bus->async_method_call(resp_handler, object_mapper,
+                                                   path, 2, interfaces);
+}
+
+/**
+ * @brief Retrieves requested chassis sensors and redundancy data from DBus .
+ * @param asyncResp   Pointer to object holding response data
+ * @param callback  Callback for next step in gathered sensor processing
+ */
+template <typename Callback>
+void getChassis(const std::shared_ptr<AsyncResp>& asyncResp,
+                Callback&& callback) {
+  CROW_LOG_DEBUG << "getChassis Done";
+  const dbus::endpoint entityManager = {
+      "xyz.openbmc_project.EntityManager",
+      "/xyz/openbmc_project/Inventory/Item/Chassis",
+      "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"};
+
+  // Process response from EntityManager and extract chassis data
+  auto resp_handler = [ callback{std::move(callback)}, asyncResp ](
+      const boost::system::error_code ec, ManagedObjectsVectorType& resp) {
+    CROW_LOG_DEBUG << "getChassis resp_handler called back Done";
+    if (ec) {
+      CROW_LOG_ERROR << "getChassis resp_handler got error " << ec;
+      asyncResp->setErrorStatus();
+      return;
+    }
+    boost::container::flat_set<std::string> sensorNames;
+    const std::string chassis_prefix =
+        "/xyz/openbmc_project/Inventory/Item/Chassis/" + asyncResp->chassisId +
+        '/';
+    CROW_LOG_DEBUG << "Chassis Prefix " << chassis_prefix;
+    bool foundChassis = false;
+    for (const auto& objDictEntry : resp) {
+      if (boost::starts_with(objDictEntry.first.value, chassis_prefix)) {
+        foundChassis = true;
+        const std::string sensorName =
+            objDictEntry.first.value.substr(chassis_prefix.size());
+        // Make sure this isn't a subobject (like a threshold)
+        const std::size_t sensorPos = sensorName.find('/');
+        if (sensorPos == std::string::npos) {
+          CROW_LOG_DEBUG << "Adding sensor " << sensorName;
+
+          sensorNames.emplace(sensorName);
+        }
+      }
+    };
+    CROW_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
+
+    if (!foundChassis) {
+      CROW_LOG_INFO << "Unable to find chassis named " << asyncResp->chassisId;
+      asyncResp->res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
+    } else {
+      callback(sensorNames);
+    }
+  };
+
+  // Make call to EntityManager to find all chassis objects
+  crow::connections::system_bus->async_method_call(resp_handler, entityManager);
+}
+
+/**
+ * @brief Builds a json sensor representation of a sensor.
+ * @param sensorName  The name of the sensor to be built
+ * @param sensorType  The type (temperature, fan_tach, ect) of the sensor to
+ * build
+ * @param interfacesDict  A dictionary of the interfaces and properties of said
+ * interfaces to be built from
+ * @param sensor_json  The json object to fill
+ */
+void objectInterfacesToJson(
+    const std::string& sensorName, const std::string& sensorType,
+    const boost::container::flat_map<
+        std::string,
+        boost::container::flat_map<dbus::string, dbus::dbus_variant>>&
+        interfacesDict,
+    nlohmann::json& sensor_json) {
+  // We need a value interface before we can do anything with it
+  auto value_it = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
+  if (value_it == interfacesDict.end()) {
+    CROW_LOG_ERROR << "Sensor doesn't have a value interface";
+    return;
+  }
+
+  // Assume values exist as is (10^0 == 1) if no scale exists
+  int64_t scaleMultiplier = 0;
+
+  auto scale_it = value_it->second.find("Scale");
+  // If a scale exists, pull value as int64, and use the scaling.
+  if (scale_it != value_it->second.end()) {
+    const int64_t* int64Value = boost::get<int64_t>(&scale_it->second);
+    if (int64Value != nullptr) {
+      scaleMultiplier = *int64Value;
+    }
+  }
+
+  sensor_json["MemberId"] = sensorName;
+  sensor_json["Name"] = sensorName;
+  sensor_json["Status"]["State"] = "Enabled";
+  sensor_json["Status"]["Health"] = "OK";
+
+  // Parameter to set to override the type we get from dbus, and force it to
+  // int, regardless of what is available.  This is used for schemas like fan,
+  // that require integers, not floats.
+  bool forceToInt = false;
+
+  const char* unit = "Reading";
+  if (sensorType == "temperature") {
+    unit = "ReadingCelsius";
+    // TODO(ed) Documentation says that path should be type fan_tach,
+    // implementation seems to implement fan
+  } else if (sensorType == "fan" || sensorType == "fan_tach") {
+    unit = "Reading";
+    sensor_json["ReadingUnits"] = "RPM";
+    forceToInt = true;
+  } else if (sensorType == "voltage") {
+    unit = "ReadingVolts";
+  } else {
+    CROW_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
+    return;
+  }
+  // Map of dbus interface name, dbus property name and redfish property_name
+  std::vector<std::tuple<const char*, const char*, const char*>> properties;
+  properties.reserve(7);
+
+  properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
+  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                          "WarningHigh", "UpperThresholdNonCritical");
+  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                          "WarningLow", "LowerThresholdNonCritical");
+  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                          "CriticalHigh", "UpperThresholdCritical");
+  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                          "CriticalLow", "LowerThresholdCritical");
+
+  if (sensorType == "temperature") {
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                            "MinReadingRangeTemp");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                            "MaxReadingRangeTemp");
+  } else {
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                            "MinReadingRange");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                            "MaxReadingRange");
+  }
+
+  for (const std::tuple<const char*, const char*, const char*>& p :
+       properties) {
+    auto interfaceProperties = interfacesDict.find(std::get<0>(p));
+    if (interfaceProperties != interfacesDict.end()) {
+      auto value_it = interfaceProperties->second.find(std::get<1>(p));
+      if (value_it != interfaceProperties->second.end()) {
+        const dbus::dbus_variant& valueVariant = value_it->second;
+        nlohmann::json& value_it = sensor_json[std::get<2>(p)];
+        // Attempt to pull the int64 directly
+        const int64_t* int64Value = boost::get<int64_t>(&valueVariant);
+
+        if (int64Value != nullptr) {
+          if (forceToInt || scaleMultiplier >= 0) {
+            value_it = *int64Value * std::pow(10, scaleMultiplier);
+          } else {
+            value_it = *int64Value *
+                       std::pow(10, static_cast<double>(scaleMultiplier));
+          }
+        }
+        // Attempt to pull the float directly
+        const double* doubleValue = boost::get<double>(&valueVariant);
+
+        if (doubleValue != nullptr) {
+          if (!forceToInt) {
+            value_it = *doubleValue *
+                       std::pow(10, static_cast<double>(scaleMultiplier));
+          } else {
+            value_it = static_cast<int64_t>(*doubleValue *
+                                            std::pow(10, scaleMultiplier));
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * @brief Entry point for retrieving sensors data related to requested
+ *        chassis.
+ * @param asyncResp   Pointer to object holding response data
+ */
+void getChassisData(const std::shared_ptr<AsyncResp>& asyncResp) {
+  CROW_LOG_DEBUG << "getChassisData";
+  auto getChassisCb = [&, asyncResp](boost::container::flat_set<std::string>&
+                                         sensorNames) {
+    CROW_LOG_DEBUG << "getChassisCb Done";
+    auto getConnectionCb =
+        [&, asyncResp, sensorNames](
+            const boost::container::flat_set<std::string>& connections) {
+          CROW_LOG_DEBUG << "getConnectionCb Done";
+          // Get managed objects from all services exposing sensors
+          for (const std::string& connection : connections) {
+            // Response handler to process managed objects
+            auto getManagedObjectsCb = [&, asyncResp, sensorNames](
+                                           const boost::system::error_code ec,
+                                           ManagedObjectsVectorType& resp) {
+              // Go through all objects and update response with
+              // sensor data
+              for (const auto& objDictEntry : resp) {
+                const std::string& objPath = objDictEntry.first.value;
+                CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
+                               << objPath;
+                if (!boost::starts_with(objPath, DBUS_SENSOR_PREFIX)) {
+                  CROW_LOG_ERROR << "Got path that isn't in sensor namespace: "
+                                 << objPath;
+                  continue;
+                }
+                std::vector<std::string> split;
+                // Reserve space for
+                // /xyz/openbmc_project/Sensors/<name>/<subname>
+                split.reserve(6);
+                boost::algorithm::split(split, objPath, boost::is_any_of("/"));
+                if (split.size() < 6) {
+                  CROW_LOG_ERROR << "Got path that isn't long enough "
+                                 << objPath;
+                  continue;
+                }
+                // These indexes aren't intuitive, as boost::split puts an empty
+                // string at the beggining
+                const std::string& sensorType = split[4];
+                const std::string& sensorName = split[5];
+                CROW_LOG_DEBUG << "sensorName " << sensorName << " sensorType "
+                               << sensorType;
+                if (sensorNames.find(sensorName) == sensorNames.end()) {
+                  CROW_LOG_ERROR << sensorName << " not in sensor list ";
+                  continue;
+                }
+
+                const char* fieldName = nullptr;
+                if (sensorType == "temperature") {
+                  fieldName = "Temperatures";
+                } else if (sensorType == "fan" || sensorType == "fan_tach") {
+                  fieldName = "Fans";
+                } else if (sensorType == "voltage") {
+                  fieldName = "Voltages";
+                } else if (sensorType == "current") {
+                  fieldName = "PowerSupply";
+                } else if (sensorType == "power") {
+                  fieldName = "PowerSupply";
+                } else {
+                  CROW_LOG_ERROR << "Unsure how to handle sensorType "
+                                 << sensorType;
+                  continue;
+                }
+
+                nlohmann::json& temp_array =
+                    asyncResp->res.json_value[fieldName];
+
+                // Create the array if it doesn't yet exist
+                if (temp_array.is_array() == false) {
+                  temp_array = nlohmann::json::array();
+                }
+
+                temp_array.push_back(nlohmann::json::object());
+                nlohmann::json& sensor_json = temp_array.back();
+                sensor_json["@odata.id"] = "/redfish/v1/Chassis/" +
+                                           asyncResp->chassisId + "/Thermal#/" +
+                                           sensorName;
+                objectInterfacesToJson(sensorName, sensorType,
+                                       objDictEntry.second, sensor_json);
+              }
+            };
+
+            dbus::endpoint ep(connection, "/xyz/openbmc_project/Sensors",
+                              "org.freedesktop.DBus.ObjectManager",
+                              "GetManagedObjects");
+            crow::connections::system_bus->async_method_call(
+                getManagedObjectsCb, ep);
+          };
+        };
+    // Get connections and then pass it to get sensors
+    getConnections(asyncResp, sensorNames, std::move(getConnectionCb));
+  };
+
+  // Get chassis information related to sensors
+  getChassis(asyncResp, std::move(getChassisCb));
+};
+
+}  // namespace redfish
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
new file mode 100644
index 0000000..b33c80f
--- /dev/null
+++ b/redfish-core/lib/thermal.hpp
@@ -0,0 +1,60 @@
+/*
+// 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 "node.hpp"
+#include "sensors.hpp"
+
+namespace redfish {
+
+class Thermal : public Node {
+ public:
+  Thermal(CrowApp& app)
+      : Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string()) {
+    Node::json["@odata.type"] = "#Thermal.v1_2_0.Thermal";
+    Node::json["@odata.context"] = "/redfish/v1/$metadata#Thermal.Thermal";
+    Node::json["Id"] = "Thermal";
+    Node::json["Name"] = "Thermal";
+
+    entityPrivileges = {{crow::HTTPMethod::GET, {{"Login"}}},
+                        {crow::HTTPMethod::HEAD, {{"Login"}}},
+                        {crow::HTTPMethod::PATCH, {{"ConfigureManager"}}},
+                        {crow::HTTPMethod::PUT, {{"ConfigureManager"}}},
+                        {crow::HTTPMethod::DELETE, {{"ConfigureManager"}}},
+                        {crow::HTTPMethod::POST, {{"ConfigureManager"}}}};
+  }
+
+ private:
+  void doGet(crow::response& res, const crow::request& req,
+             const std::vector<std::string>& params) override {
+    if (params.size() != 1) {
+      res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+      res.end();
+      return;
+    }
+    const std::string& chassis_name = params[0];
+
+    res.json_value = Node::json;
+    auto asyncResp = std::make_shared<AsyncResp>(
+        res, chassis_name,
+        std::initializer_list<const char*>{
+            "/xyz/openbmc_project/Sensors/fan",
+            "/xyz/openbmc_project/Sensors/temperature"});
+    getChassisData(asyncResp);
+  }
+};
+
+}  // namespace redfish
