incremental
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 501c2c0..58dd0bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,11 +7,6 @@
 SET(BUILD_SHARED_LIBRARIES OFF)
 
 #SET(HUNTER_STATUS_DEBUG ON)
-
-
-# Debug information
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer")
-
 #SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -fno-rtti")
 #SET(CMAKE_C_FLAGS  "${CMAKE_C_FLAGS} -fno-rtti")
 include("cmake/HunterGate.cmake")
@@ -131,6 +126,10 @@
 #add_subdirectory(libjpeg)
 
 
+# dbus
+hunter_add_package(dbus)
+find_package(dbus REQUIRED) # Include functions provided by PkgConfig module.
+
 # Crow
 add_definitions(-DCROW_DISABLE_LOGGING)
 add_definitions(-DCROW_ENABLE_SSL)
@@ -214,7 +213,7 @@
 if(${BUILD_UT})
     # big list of naughty strings
     add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/generated/blns.hpp
-        COMMAND xxd -i ${CMAKE_CURRENT_SOURCE_DIR}/src/test_resources/blns.txt ${CMAKE_BINARY_DIR}/generated/blns.hpp)
+        COMMAND xxd -i ${CMAKE_CURRENT_SOURCE_DIR}/src/test_resources/blns ${CMAKE_BINARY_DIR}/generated/blns.hpp)
 
     # googletest
     enable_testing()
@@ -241,6 +240,18 @@
 target_link_libraries(bmcweb g3logger)
 target_link_libraries(bmcweb ${ZLIB_LIBRARIES})
 add_dependencies(bmcweb packagestaticcpp)
+target_link_libraries(bmcweb  dbus::dbus)
+
+# dbus
+add_executable(dbus_test src/dbus_main.cpp
+boost-dbus/include/dbus/impl/connection.ipp
+boost-dbus/include/dbus/impl/filter.ipp
+boost-dbus/include/dbus/impl/match.ipp
+boost-dbus/include/dbus/impl/message_iterator.ipp
+boost-dbus/include/dbus/impl/message.ipp
+boost-dbus/include/dbus/impl/packer.ipp
+boost-dbus/include/dbus/impl/unpacker.ipp)
+target_link_libraries(dbus_test  dbus::dbus)
 
 # udpclient
 #add_executable(udpclient src/udpclient.cpp)
diff --git a/scripts/build_web_assets.py b/scripts/build_web_assets.py
index 264448e..0b82cbc 100755
--- a/scripts/build_web_assets.py
+++ b/scripts/build_web_assets.py
@@ -98,7 +98,6 @@
         if re.search("partial-.*\\.html", relative_path):
             sha1_path = get_sha1_path_from_relative(relative_path, sha1_list[relative_path])
 
-            print("full_filepath" + full_filepath)
             preload_string += (
                 "<script type=\"text/ng-template\" id=\"" + sha1_path + "\">\n" +
                 open(full_filepath, 'r').read() +
@@ -207,7 +206,7 @@
             full_filepath)
         extension = os.path.splitext(relative_path)[1]
 
-        print("Including {:<40} size {:>7}".format(
+        print("Including {:<40} raw size {:>7}".format(
             relative_path, len(file_content)))
 
         if extension == ".html" or relative_path == "/":
@@ -319,6 +318,7 @@
                     relative_path_escaped=relative_path_escaped
                 )
             )
+            print("{:<40} took {:<7} kbytes".format(relative_path_escaped, len(array_binary_text)/1024))
         cpp_output.write("}\n}\n")
 
     print("Total static file size: {}KB".format(int(total_payload_size/1024)))
diff --git a/src/dbus_main.cpp b/src/dbus_main.cpp
new file mode 100644
index 0000000..6cee92e
--- /dev/null
+++ b/src/dbus_main.cpp
@@ -0,0 +1,455 @@
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <boost/iostreams/stream.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+
+/**
+ * Connect to the DBUS bus and send a broadcast signal
+ */
+void sendsignal(char* sigvalue) {
+  DBusMessage* msg;
+  DBusMessageIter args;
+  DBusConnection* conn;
+  DBusError err;
+  int ret;
+  dbus_uint32_t serial = 0;
+
+  printf("Sending signal with value %s\n", sigvalue);
+
+  // initialise the error value
+  dbus_error_init(&err);
+
+  // connect to the DBUS system bus, and check for errors
+  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Connection Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (NULL == conn) {
+    exit(1);
+  }
+
+  // register our name on the bus, and check for errors
+  ret = dbus_bus_request_name(conn, "test.signal.source",
+                              DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Name Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+    exit(1);
+  }
+
+  // create a signal & check for errors
+  msg = dbus_message_new_signal(
+      "/test/signal/Object",  // object name of the signal
+      "test.signal.Type",     // interface name of the signal
+      "Test");                // name of the signal
+  if (NULL == msg) {
+    fprintf(stderr, "Message Null\n");
+    exit(1);
+  }
+
+  // append arguments onto signal
+  dbus_message_iter_init_append(msg, &args);
+  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+
+  // send the message and flush the connection
+  if (!dbus_connection_send(conn, msg, &serial)) {
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+  dbus_connection_flush(conn);
+
+  printf("Signal Sent\n");
+
+  // free the message and close the connection
+  dbus_message_unref(msg);
+  dbus_connection_close(conn);
+}
+
+/**
+ * Call a method on a remote object
+ */
+void query(const char* param) {
+  DBusMessage* msg;
+  DBusMessageIter args;
+  DBusConnection* conn;
+  DBusError err;
+  DBusPendingCall* pending;
+  int ret;
+  bool stat;
+  dbus_uint32_t level;
+
+  printf("Calling remote method with %s\n", param);
+
+  // initialiset the errors
+  dbus_error_init(&err);
+
+  // connect to the system bus and check for errors
+  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Connection Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (NULL == conn) {
+    exit(1);
+  }
+  /*
+  // request our name on the bus
+  ret = dbus_bus_request_name(conn, "test.method.caller",
+  DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+  if (dbus_error_is_set(&err)) {
+     fprintf(stderr, "Name Error (%s)\n", err.message);
+     dbus_error_free(&err);
+  }
+  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+     exit(1);
+  }
+  */
+
+  // create a new method call and check for errors
+  msg = dbus_message_new_method_call(
+      "org.freedesktop.Avahi",         // target for the method call
+      "/",                             // object to call on
+      "org.freedesktop.Avahi.Server",  // interface to call on
+      "GetHostName");                  // method name
+  if (NULL == msg) {
+    fprintf(stderr, "Message Null\n");
+    exit(1);
+  }
+
+  // append arguments
+  /*
+  dbus_message_iter_init_append(msg, &args);
+  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) {
+     fprintf(stderr, "Out Of Memory!\n");
+     exit(1);
+  }
+  */
+  // send message and get a handle for a reply
+  if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                       -1)) {  // -1 is default timeout
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+  if (NULL == pending) {
+    fprintf(stderr, "Pending Call Null\n");
+    exit(1);
+  }
+  dbus_connection_flush(conn);
+
+  printf("Request Sent\n");
+
+  // free message
+  dbus_message_unref(msg);
+
+  // block until we recieve a reply
+  dbus_pending_call_block(pending);
+
+  // get the reply message
+  msg = dbus_pending_call_steal_reply(pending);
+  if (NULL == msg) {
+    fprintf(stderr, "Reply Null\n");
+    exit(1);
+  }
+  // free the pending message handle
+  dbus_pending_call_unref(pending);
+
+  // read the parameters
+  char* str = NULL;
+  if (!dbus_message_iter_init(msg, &args))
+    fprintf(stderr, "Message has no arguments!\n");
+  else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
+    fprintf(stderr, "Argument is not boolean!\n");
+  else
+    dbus_message_iter_get_basic(&args, &str);
+
+  printf("Got Reply: %s\n", str);
+
+  // free reply and close connection
+  dbus_message_unref(msg);
+  dbus_connection_close(conn);
+}
+
+void list_names() {
+  DBusError err;
+
+  int ret;
+  bool stat;
+  dbus_uint32_t level;
+
+  // initialiset the errors
+  dbus_error_init(&err);
+
+  // connect to the system bus and check for errors
+  DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Connection Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (NULL == conn) {
+    exit(1);
+  }
+
+  // create a new method call and check for errors
+  DBusMessage* msg = dbus_message_new_method_call(
+      "org.freedesktop.DBus",  // target for the method call
+      "/",                     // object to call on
+      "org.freedesktop.DBus",  // interface to call on
+      "ListNames");            // method name
+  if (NULL == msg) {
+    fprintf(stderr, "Message Null\n");
+    exit(1);
+  }
+
+  DBusPendingCall* pending;
+  // send message and get a handle for a reply
+  if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                       -1)) {  // -1 is default timeout
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+  if (NULL == pending) {
+    fprintf(stderr, "Pending Call Null\n");
+    exit(1);
+  }
+  dbus_connection_flush(conn);
+
+  // free message
+  dbus_message_unref(msg);
+
+  // block until we recieve a reply
+  dbus_pending_call_block(pending);
+
+  // get the reply message
+  msg = dbus_pending_call_steal_reply(pending);
+  if (NULL == msg) {
+    fprintf(stderr, "Reply Null\n");
+    exit(1);
+  }
+  // free the pending message handle
+  dbus_pending_call_unref(pending);
+
+  // read the parameters
+  DBusMessageIter args;
+  DBusMessageIter strings;
+  char* paths = NULL;
+  if (!dbus_message_iter_init(msg, &args)) {
+    fprintf(stderr, "Message has no arguments!\n");
+  }
+  std::vector<std::string> names;
+  do {
+    dbus_message_iter_recurse(&args, &strings);
+    do {
+      dbus_message_iter_get_basic(&strings, &paths);
+      names.emplace_back(paths);
+    } while (dbus_message_iter_next(&strings));
+  } while (dbus_message_iter_next(&args));
+
+  // free reply and close connection
+  dbus_message_unref(msg);
+  dbus_connection_close(conn);
+}
+
+std::vector<std::string> read_dbus_xml_names(std::string& xml_data) {
+  std::vector<std::string> values;
+  // populate tree structure pt
+  using boost::property_tree::ptree;
+  ptree pt;
+  boost::iostreams::stream<boost::iostreams::array_source> stream(
+      xml_data.c_str(), xml_data.size());
+  read_xml(stream, pt);
+
+  // traverse node to find other nodes
+  for (const auto& interface : pt.get_child("node")) {
+    if (interface.first == "node") {
+      auto t = interface.second.get<std::string>("<xmlattr>", "default");
+      for (const auto& subnode : interface.second.get_child("<xmlattr>")) {
+        if (subnode.first == "name") {
+          auto t = subnode.second.get("", "unknown");
+          values.emplace_back(std::move(t));
+        }
+      }
+    }
+  }
+  return values;
+}
+
+using sensor_values=std::vector<std::pair<std::string, int32_t>>;
+
+sensor_values read_sensor_values() {
+  sensor_values values;
+  DBusError err;
+
+  int ret;
+  bool stat;
+  dbus_uint32_t level;
+
+  // initialiset the errors
+  dbus_error_init(&err);
+
+  // connect to the system bus and check for errors
+  DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Connection Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (NULL == conn) {
+    exit(1);
+  }
+
+  // create a new method call and check for errors
+  DBusMessage* msg = dbus_message_new_method_call(
+      "org.openbmc.Sensors",                  // target for the method call
+      "/org/openbmc/sensors/tach",            // object to call on
+      "org.freedesktop.DBus.Introspectable",  // interface to call on
+      "Introspect");                          // method name
+  if (NULL == msg) {
+    fprintf(stderr, "Message Null\n");
+    exit(1);
+  }
+
+  DBusPendingCall* pending;
+  // send message and get a handle for a reply
+  if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                       -1)) {  // -1 is default timeout
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+  if (NULL == pending) {
+    fprintf(stderr, "Pending Call Null\n");
+    exit(1);
+  }
+  dbus_connection_flush(conn);
+
+  // free message
+  dbus_message_unref(msg);
+
+  // block until we recieve a reply
+  dbus_pending_call_block(pending);
+
+  // get the reply message
+  msg = dbus_pending_call_steal_reply(pending);
+  if (NULL == msg) {
+    fprintf(stderr, "Reply Null\n");
+    exit(1);
+  }
+  // free the pending message handle
+  dbus_pending_call_unref(pending);
+
+  // read the parameters
+  DBusMessageIter args;
+  char* xml_struct = NULL;
+  if (!dbus_message_iter_init(msg, &args)) {
+    fprintf(stderr, "Message has no arguments!\n");
+  }
+
+  // read the arguments
+  if (!dbus_message_iter_init(msg, &args)) {
+    fprintf(stderr, "Message has no arguments!\n");
+  } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
+    fprintf(stderr, "Argument is not string!\n");
+  } else {
+    dbus_message_iter_get_basic(&args, &xml_struct);
+  }
+  std::vector<std::string> methods;
+  if (xml_struct != NULL) {
+    std::string xml_data(xml_struct);
+    methods = read_dbus_xml_names(xml_data);
+  }
+
+  fprintf(stdout, "Found %ld sensors \n", methods.size());
+
+  for (auto& method : methods) {
+    // TODO(Ed) make sure sensor exposes SensorValue interface
+    // create a new method call and check for errors
+    DBusMessage* msg = dbus_message_new_method_call(
+        "org.openbmc.Sensors",                  // target for the method call
+        ("/org/openbmc/sensors/tach/" + method).c_str(),  // object to call on
+        "org.openbmc.SensorValue",              // interface to call on
+        "getValue");                            // method name
+    if (NULL == msg) {
+      fprintf(stderr, "Message Null\n");
+      exit(1);
+    }
+
+    DBusPendingCall* pending;
+    // send message and get a handle for a reply
+    if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                         -1)) {  // -1 is default timeout
+      fprintf(stderr, "Out Of Memory!\n");
+      exit(1);
+    }
+    if (NULL == pending) {
+      fprintf(stderr, "Pending Call Null\n");
+      exit(1);
+    }
+    dbus_connection_flush(conn);
+
+    // free message
+    dbus_message_unref(msg);
+
+    // block until we recieve a reply
+    dbus_pending_call_block(pending);
+
+    // get the reply message
+    msg = dbus_pending_call_steal_reply(pending);
+    if (NULL == msg) {
+      fprintf(stderr, "Reply Null\n");
+      exit(1);
+    }
+    // free the pending message handle
+    dbus_pending_call_unref(pending);
+
+    // read the parameters
+    DBusMessageIter args;
+    int32_t value;
+    if (!dbus_message_iter_init(msg, &args)) {
+      fprintf(stderr, "Message has no arguments!\n");
+    }
+
+    // read the arguments
+    if (!dbus_message_iter_init(msg, &args)) {
+      fprintf(stderr, "Message has no arguments!\n");
+    } else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) {
+      fprintf(stderr, "Argument is not string!\n");
+    } else {
+      DBusMessageIter sub;
+      dbus_message_iter_recurse(&args, &sub);
+      auto type = dbus_message_iter_get_arg_type(&sub);
+      if (DBUS_TYPE_INT32 != type) {
+        fprintf(stderr, "Variant subType is not int32 it is %d\n", type);
+      } else {
+        dbus_message_iter_get_basic(&sub, &value);
+        values.emplace_back(method.c_str(), value);
+      }
+    }
+  }
+
+  // free reply and close connection
+  dbus_message_unref(msg);
+  return values;
+}
+
+
+int main(int argc, char** argv) {
+  auto values = read_sensor_values();
+
+  for (auto value: values){
+    std::cout << value.first << ": " << value.second << "\n";
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/src/test_resources/blns.txt b/src/test_resources/blns
similarity index 100%
rename from src/test_resources/blns.txt
rename to src/test_resources/blns
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 2ec7e37..82b83a7 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -31,11 +31,196 @@
 #include <boost/asio.hpp>
 #include <boost/endian/arithmetic.hpp>
 
+#include <dbus/dbus.h>
+#include <boost/iostreams/stream.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+
 #include <iostream>
 #include <memory>
 #include <string>
 #include <unordered_set>
 
+using sensor_values = std::vector<std::pair<std::string, int32_t>>;
+
+std::vector<std::string> read_dbus_xml_names(std::string& xml_data) {
+  std::vector<std::string> values;
+  // populate tree structure pt
+  using boost::property_tree::ptree;
+  ptree pt;
+  boost::iostreams::stream<boost::iostreams::array_source> stream(
+      xml_data.c_str(), xml_data.size());
+  read_xml(stream, pt);
+
+  // traverse node to find other nodes
+  for (const auto& interface : pt.get_child("node")) {
+    if (interface.first == "node") {
+      auto t = interface.second.get<std::string>("<xmlattr>", "default");
+      for (const auto& subnode : interface.second.get_child("<xmlattr>")) {
+        if (subnode.first == "name") {
+          auto t = subnode.second.get("", "unknown");
+          values.emplace_back(std::move(t));
+        }
+      }
+    }
+  }
+  return values;
+}
+
+sensor_values read_sensor_values() {
+  sensor_values values;
+  DBusError err;
+
+  int ret;
+  bool stat;
+  dbus_uint32_t level;
+
+  // initialiset the errors
+  dbus_error_init(&err);
+
+  // connect to the system bus and check for errors
+  DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+  if (dbus_error_is_set(&err)) {
+    fprintf(stderr, "Connection Error (%s)\n", err.message);
+    dbus_error_free(&err);
+  }
+  if (NULL == conn) {
+    exit(1);
+  }
+
+  // create a new method call and check for errors
+  DBusMessage* msg = dbus_message_new_method_call(
+      "org.openbmc.Sensors",                  // target for the method call
+      "/org/openbmc/sensors/tach",            // object to call on
+      "org.freedesktop.DBus.Introspectable",  // interface to call on
+      "Introspect");                          // method name
+  if (NULL == msg) {
+    fprintf(stderr, "Message Null\n");
+    exit(1);
+  }
+
+  DBusPendingCall* pending;
+  // send message and get a handle for a reply
+  if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                       -1)) {  // -1 is default timeout
+    fprintf(stderr, "Out Of Memory!\n");
+    exit(1);
+  }
+  if (NULL == pending) {
+    fprintf(stderr, "Pending Call Null\n");
+    exit(1);
+  }
+  dbus_connection_flush(conn);
+
+  // free message
+  dbus_message_unref(msg);
+
+  // block until we recieve a reply
+  dbus_pending_call_block(pending);
+
+  // get the reply message
+  msg = dbus_pending_call_steal_reply(pending);
+  if (NULL == msg) {
+    fprintf(stderr, "Reply Null\n");
+    exit(1);
+  }
+  // free the pending message handle
+  dbus_pending_call_unref(pending);
+
+  // read the parameters
+  DBusMessageIter args;
+  char* xml_struct = NULL;
+  if (!dbus_message_iter_init(msg, &args)) {
+    fprintf(stderr, "Message has no arguments!\n");
+  }
+
+  // read the arguments
+  if (!dbus_message_iter_init(msg, &args)) {
+    fprintf(stderr, "Message has no arguments!\n");
+  } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
+    fprintf(stderr, "Argument is not string!\n");
+  } else {
+    dbus_message_iter_get_basic(&args, &xml_struct);
+  }
+  std::vector<std::string> methods;
+  if (xml_struct != NULL) {
+    std::string xml_data(xml_struct);
+    methods = read_dbus_xml_names(xml_data);
+  }
+
+  fprintf(stdout, "Found %ld sensors \n", methods.size());
+
+  for (auto& method : methods) {
+    // TODO(Ed) make sure sensor exposes SensorValue interface
+    // create a new method call and check for errors
+    DBusMessage* msg = dbus_message_new_method_call(
+        "org.openbmc.Sensors",  // target for the method call
+        ("/org/openbmc/sensors/tach/" + method).c_str(),  // object to call on
+        "org.openbmc.SensorValue",  // interface to call on
+        "getValue");                // method name
+    if (NULL == msg) {
+      fprintf(stderr, "Message Null\n");
+      exit(1);
+    }
+
+    DBusPendingCall* pending;
+    // send message and get a handle for a reply
+    if (!dbus_connection_send_with_reply(conn, msg, &pending,
+                                         -1)) {  // -1 is default timeout
+      fprintf(stderr, "Out Of Memory!\n");
+      exit(1);
+    }
+    if (NULL == pending) {
+      fprintf(stderr, "Pending Call Null\n");
+      exit(1);
+    }
+    dbus_connection_flush(conn);
+
+    // free message
+    dbus_message_unref(msg);
+
+    // block until we recieve a reply
+    dbus_pending_call_block(pending);
+
+    // get the reply message
+    msg = dbus_pending_call_steal_reply(pending);
+    if (NULL == msg) {
+      fprintf(stderr, "Reply Null\n");
+      exit(1);
+    }
+    // free the pending message handle
+    dbus_pending_call_unref(pending);
+
+    // read the parameters
+    DBusMessageIter args;
+    int32_t value;
+    if (!dbus_message_iter_init(msg, &args)) {
+      fprintf(stderr, "Message has no arguments!\n");
+    }
+
+    // read the arguments
+    if (!dbus_message_iter_init(msg, &args)) {
+      fprintf(stderr, "Message has no arguments!\n");
+    } else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) {
+      fprintf(stderr, "Argument is not string!\n");
+    } else {
+      DBusMessageIter sub;
+      dbus_message_iter_recurse(&args, &sub);
+      auto type = dbus_message_iter_get_arg_type(&sub);
+      if (DBUS_TYPE_INT32 != type) {
+        fprintf(stderr, "Variant subType is not int32 it is %d\n", type);
+      } else {
+        dbus_message_iter_get_basic(&sub, &value);
+        values.emplace_back(method.c_str(), value);
+      }
+    }
+  }
+
+  // free reply and close connection
+  dbus_message_unref(msg);
+  return values;
+}
+
 int main(int argc, char** argv) {
   auto worker(g3::LogWorker::createLogWorker());
   std::string logger_name("bmcweb");
@@ -114,6 +299,18 @@
         conn.send_binary(str);
 
       });
+
+  CROW_ROUTE(app, "/sensortest")
+  ([]() {
+    crow::json::wvalue j;
+    auto values = read_sensor_values();
+    for (auto& pair : values) {
+      j[pair.first] = pair.second;
+    }
+
+    return j;
+  });
+
   auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file);
   app.port(18080)
       //.ssl(std::move(ssl_context))
diff --git a/static/CMakeLists.txt b/static/CMakeLists.txt
index acfc8a8..183eeb2 100644
--- a/static/CMakeLists.txt
+++ b/static/CMakeLists.txt
@@ -8,6 +8,8 @@
     js/kvmController.js
     js/loginController.js
     js/ipmiController.js
+    js/versionController.js
+    js/sensorController.js
     js/angular-resource.js
     js/angular-sanitize.js
     js/bmcApp.js
@@ -15,7 +17,7 @@
     js/angular-animate.js
     js/run_prettify.js
     js/angular.js
-    js/versionController.js
+    
     noVNC/core/inflator.js
     noVNC/core/input/xtscancodes.js
     noVNC/core/input/util.js
@@ -51,6 +53,7 @@
     partial-home-list.html
     partial-ipmi.html
     partial-kvm.html
+    partial-sensor.html
     partial-systeminfo.html
 )
 
diff --git a/static/index.html b/static/index.html
index 687aa64..de7f47c 100644
--- a/static/index.html
+++ b/static/index.html
@@ -31,6 +31,7 @@
     <script type="text/javascript" src="static/js/loginController.js" defer></script>
     <script type="text/javascript" src="static/js/kvmController.js" defer></script>
     <script type="text/javascript" src="static/js/ipmiController.js" defer></script>
+    <script type="text/javascript" src="static/js/sensorController.js" defer></script>
 
     <script type="text/javascript" src="static/noVNC/core/util.js" defer></script>
     <script type="text/javascript" src="static/noVNC/app/webutil.js" defer></script>
@@ -85,7 +86,7 @@
                         <li class="dropdown" uib-dropdown dropdown-append-to-body>
                             <a href="#" class="dropdown-toggle" uib-dropdown-toggle role="button" aria-haspopup="true" aria-expanded="false">Server Health <span class="caret"></span></a>
                             <ul class="dropdown-menu" uib-dropdown-menu role="menu">
-                                <li><a href="#">Sensor Information</a></li>
+                                <li><a ui-sref="sensor">Sensor Information</a></li>
                                 <li><a ui-sref="eventlog">Event Log</a></li>
                             </ul>
                         </li>
diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js
index 2678ac0..7575e34 100644
--- a/static/js/bmcApp.js
+++ b/static/js/bmcApp.js
@@ -130,6 +130,9 @@
       .state(
           'ipmi', {url: '/ipmi', templateUrl: 'static/partial-ipmi.html'})
 
+      .state(
+          'sensor', {url: '/sensor', templateUrl: 'static/partial-sensor.html'})
+
       // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
       .state('about', {url: '/about', templateUrl: 'static/partial-fruinfo.html'})
 
diff --git a/static/js/sensorController.js b/static/js/sensorController.js
new file mode 100644
index 0000000..3554c0f
--- /dev/null
+++ b/static/js/sensorController.js
@@ -0,0 +1,11 @@
+angular.module('bmcApp').controller('sensorController', [
+  '$scope', '$resource',
+  function($scope, $resource) {
+
+    var systeminfo = $resource("/sensortest");
+    systeminfo.get(function(sensor_values) {
+      $scope.sensor_values = sensor_values;
+    });
+
+  }
+]);
\ No newline at end of file
diff --git a/static/partial-sensor.html b/static/partial-sensor.html
new file mode 100644
index 0000000..09f1cad
--- /dev/null
+++ b/static/partial-sensor.html
@@ -0,0 +1,28 @@
+<div class="container" ng-controller="sensorController">
+    <div class="row">
+        <div class="col-lg-8">
+            <div class="box box-primary">
+                <div class="box-header with-border">
+                    <h4>Summary
+                        <h4>
+                </div>
+                <div class="box-body">
+                    <table class="table table-striped system-status-table">
+                        <thead>
+                            <tr>
+                                <th>Sensor</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr ng-repeat="(sensor_name, value) in sensor_values">
+                                <td class="fit">{{ sensor_name }}</td>
+                                <td class="fit">{{ value }}</td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
\ No newline at end of file