diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js
index 55e4a42..1812261 100644
--- a/static/js/bmcApp.js
+++ b/static/js/bmcApp.js
@@ -1,8 +1,15 @@
 'use strict';
 angular.module('Authentication', []);
 var app = angular.module('bmcApp', [
-  'ngCookies', 'ngAnimate', 'ngSanitize', 'ui.bootstrap',
-  'ui.router', 'ngWebSocket', 'Authentication', 'ui.router.modal',
+  'ngCookies',
+  'ngAnimate',
+  'ngSanitize',
+  'ui.bootstrap',
+  'ui.router',
+  'ngWebSocket',
+  'Authentication',
+  'ui.router.modal',
+  'smart-table',
 ]);
 
 app.service('loginInterceptor', [
@@ -128,7 +135,7 @@
         .state('fwupdate.confirm', {
           url : '/confirm',
           templateUrl : 'static/partial-fwupdateconfirm.html',
-          modal: true
+          modal : true
         })
         // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
         .state('about',
@@ -216,7 +223,7 @@
     };
 
     service.IsLoggedIn = function() {
-      if ($rootScope.globals['currentUser']){
+      if ($rootScope.globals['currentUser']) {
         return true;
       } else {
         return false;
diff --git a/static/js/sensorController.js b/static/js/sensorController.js
index 67c9d82..0fa9045 100644
--- a/static/js/sensorController.js
+++ b/static/js/sensorController.js
@@ -1,41 +1,54 @@
 angular.module('bmcApp').controller('sensorController', [
   '$scope', '$http', '$location', 'websocketService',
   function($scope, $http, $location, websocketService) {
-    $scope.sensor_values = {};
+    $scope.smartTablePageSize = 10;
+    $scope.next_id = 0;
+    websocketService.start('/sensorws', function(evt) {
+      var obj = JSON.parse(evt.data);
 
-    var host = $location.host();
-    var port = $location.port();
-    var protocol = "ws://";
-    if ($location.protocol() === 'https') {
-      protocol = 'wss://';
-    }
-    websocketService.start(protocol + host + ":" + port + "/sensorws", function (evt) {
-        var obj = JSON.parse(evt.data);
-        $scope.$apply(function () {
-            for (var key in obj) {
-              if (obj.hasOwnProperty(key)) {
-                console.log(key + " -> " + obj[key]);
-                $scope.sensor_values[key] = obj[key];
-              }
+      $scope.$apply(function() {
+        for (var sensor_name in obj) {
+          var found = false;
+          for (var sensor_index in $scope.rowCollection) {
+            var sensor_object = $scope.rowCollection[sensor_index];
+            if (sensor_object.name === sensor_name) {
+              sensor_object.value = obj[sensor_name];
+              found = true;
+              break;
             }
-        });
+            }
+          if (!found) {
+            console.log(sensor_name + ' -> ' + obj[sensor_name]);
+            $scope.next_id = $scope.next_id + 1;
+
+            $scope.rowCollection.push({
+              id : $scope.next_id,
+              name : sensor_name,
+              value : obj[sensor_name],
+            });
+          }
+        };
+      });
     });
 
+    $scope.rowCollection = [];
+
   }
 ]);
 
-app.factory('websocketService', function () {
-        return {
-            start: function (url, callback) {
-                var websocket = new WebSocket(url);
-                websocket.onopen = function () {
-                };
-                websocket.onclose = function () {
-                };
-                websocket.onmessage = function (evt) {
-                    callback(evt);
-                };
-            }
+app.factory('websocketService', function($location) {
+  return {
+    start: function(url, callback) {
+      var host = $location.host();
+      var port = 18080;
+      var protocol = 'wss://';
+      if ($location.protocol() === 'http') {
+        protocol = 'ws://';
         }
+      var websocket = new WebSocket(protocol + host + ':' + port + url);
+      websocket.onopen = function() {};
+      websocket.onclose = function() {};
+      websocket.onmessage = function(evt) { callback(evt); };
     }
-);
\ No newline at end of file
+  }
+});
\ No newline at end of file
diff --git a/static/js/smart-table.js b/static/js/smart-table.js
new file mode 100644
index 0000000..e0246d4
--- /dev/null
+++ b/static/js/smart-table.js
@@ -0,0 +1,534 @@
+/** 
+* @version 2.1.8
+* @license MIT
+*/
+(function (ng, undefined){
+    'use strict';
+
+ng.module('smart-table', []).run(['$templateCache', function ($templateCache) {
+    $templateCache.put('template/smart-table/pagination.html',
+        '<nav ng-if="numPages && pages.length >= 2"><ul class="pagination">' +
+        '<li ng-repeat="page in pages" ng-class="{active: page==currentPage}"><a href="javascript: void(0);" ng-click="selectPage(page)">{{page}}</a></li>' +
+        '</ul></nav>');
+}]);
+
+
+ng.module('smart-table')
+  .constant('stConfig', {
+    pagination: {
+      template: 'template/smart-table/pagination.html',
+      itemsByPage: 10,
+      displayedPages: 5
+    },
+    search: {
+      delay: 400, // ms
+      inputEvent: 'input'
+    },
+    select: {
+      mode: 'single',
+      selectedClass: 'st-selected'
+    },
+    sort: {
+      ascentClass: 'st-sort-ascent',
+      descentClass: 'st-sort-descent',
+      descendingFirst: false,
+      skipNatural: false,
+      delay:300
+    },
+    pipe: {
+      delay: 100 //ms
+    }
+  });
+ng.module('smart-table')
+  .controller('stTableController', ['$scope', '$parse', '$filter', '$attrs', function StTableController ($scope, $parse, $filter, $attrs) {
+    var propertyName = $attrs.stTable;
+    var displayGetter = $parse(propertyName);
+    var displaySetter = displayGetter.assign;
+    var safeGetter;
+    var orderBy = $filter('orderBy');
+    var filter = $filter('filter');
+    var safeCopy = copyRefs(displayGetter($scope));
+    var tableState = {
+      sort: {},
+      search: {},
+      pagination: {
+        start: 0,
+        totalItemCount: 0
+      }
+    };
+    var filtered;
+    var pipeAfterSafeCopy = true;
+    var ctrl = this;
+    var lastSelected;
+
+    function copyRefs (src) {
+      return src ? [].concat(src) : [];
+    }
+
+    function updateSafeCopy () {
+      safeCopy = copyRefs(safeGetter($scope));
+      if (pipeAfterSafeCopy === true) {
+        ctrl.pipe();
+      }
+    }
+
+    function deepDelete (object, path) {
+      if (path.indexOf('.') != -1) {
+        var partials = path.split('.');
+        var key = partials.pop();
+        var parentPath = partials.join('.');
+        var parentObject = $parse(parentPath)(object)
+        delete parentObject[key];
+        if (Object.keys(parentObject).length == 0) {
+          deepDelete(object, parentPath);
+        }
+      } else {
+        delete object[path];
+      }
+    }
+
+    if ($attrs.stSafeSrc) {
+      safeGetter = $parse($attrs.stSafeSrc);
+      $scope.$watch(function () {
+        var safeSrc = safeGetter($scope);
+        return safeSrc && safeSrc.length ? safeSrc[0] : undefined;
+      }, function (newValue, oldValue) {
+        if (newValue !== oldValue) {
+          updateSafeCopy();
+        }
+      });
+      $scope.$watch(function () {
+        var safeSrc = safeGetter($scope);
+        return safeSrc ? safeSrc.length : 0;
+      }, function (newValue, oldValue) {
+        if (newValue !== safeCopy.length) {
+          updateSafeCopy();
+        }
+      });
+      $scope.$watch(function () {
+        return safeGetter($scope);
+      }, function (newValue, oldValue) {
+        if (newValue !== oldValue) {
+          tableState.pagination.start = 0;
+          updateSafeCopy();
+        }
+      });
+    }
+
+    /**
+     * sort the rows
+     * @param {Function | String} predicate - function or string which will be used as predicate for the sorting
+     * @param [reverse] - if you want to reverse the order
+     */
+    this.sortBy = function sortBy (predicate, reverse) {
+      tableState.sort.predicate = predicate;
+      tableState.sort.reverse = reverse === true;
+
+      if (ng.isFunction(predicate)) {
+        tableState.sort.functionName = predicate.name;
+      } else {
+        delete tableState.sort.functionName;
+      }
+
+      tableState.pagination.start = 0;
+      return this.pipe();
+    };
+
+    /**
+     * search matching rows
+     * @param {String} input - the input string
+     * @param {String} [predicate] - the property name against you want to check the match, otherwise it will search on all properties
+     */
+    this.search = function search (input, predicate) {
+      var predicateObject = tableState.search.predicateObject || {};
+      var prop = predicate ? predicate : '$';
+
+      input = ng.isString(input) ? input.trim() : input;
+      $parse(prop).assign(predicateObject, input);
+      // to avoid to filter out null value
+      if (!input) {
+        deepDelete(predicateObject, prop);
+      }
+      tableState.search.predicateObject = predicateObject;
+      tableState.pagination.start = 0;
+      return this.pipe();
+    };
+
+    /**
+     * this will chain the operations of sorting and filtering based on the current table state (sort options, filtering, ect)
+     */
+    this.pipe = function pipe () {
+      var pagination = tableState.pagination;
+      var output;
+      filtered = tableState.search.predicateObject ? filter(safeCopy, tableState.search.predicateObject) : safeCopy;
+      if (tableState.sort.predicate) {
+        filtered = orderBy(filtered, tableState.sort.predicate, tableState.sort.reverse);
+      }
+      pagination.totalItemCount = filtered.length;
+      if (pagination.number !== undefined) {
+        pagination.numberOfPages = filtered.length > 0 ? Math.ceil(filtered.length / pagination.number) : 1;
+        pagination.start = pagination.start >= filtered.length ? (pagination.numberOfPages - 1) * pagination.number : pagination.start;
+        output = filtered.slice(pagination.start, pagination.start + parseInt(pagination.number));
+      }
+      displaySetter($scope, output || filtered);
+    };
+
+    /**
+     * select a dataRow (it will add the attribute isSelected to the row object)
+     * @param {Object} row - the row to select
+     * @param {String} [mode] - "single" or "multiple" (multiple by default)
+     */
+    this.select = function select (row, mode) {
+      var rows = copyRefs(displayGetter($scope));
+      var index = rows.indexOf(row);
+      if (index !== -1) {
+        if (mode === 'single') {
+          row.isSelected = row.isSelected !== true;
+          if (lastSelected) {
+            lastSelected.isSelected = false;
+          }
+          lastSelected = row.isSelected === true ? row : undefined;
+        } else {
+          rows[index].isSelected = !rows[index].isSelected;
+        }
+      }
+    };
+
+    /**
+     * take a slice of the current sorted/filtered collection (pagination)
+     *
+     * @param {Number} start - start index of the slice
+     * @param {Number} number - the number of item in the slice
+     */
+    this.slice = function splice (start, number) {
+      tableState.pagination.start = start;
+      tableState.pagination.number = number;
+      return this.pipe();
+    };
+
+    /**
+     * return the current state of the table
+     * @returns {{sort: {}, search: {}, pagination: {start: number}}}
+     */
+    this.tableState = function getTableState () {
+      return tableState;
+    };
+
+    this.getFilteredCollection = function getFilteredCollection () {
+      return filtered || safeCopy;
+    };
+
+    /**
+     * Use a different filter function than the angular FilterFilter
+     * @param filterName the name under which the custom filter is registered
+     */
+    this.setFilterFunction = function setFilterFunction (filterName) {
+      filter = $filter(filterName);
+    };
+
+    /**
+     * Use a different function than the angular orderBy
+     * @param sortFunctionName the name under which the custom order function is registered
+     */
+    this.setSortFunction = function setSortFunction (sortFunctionName) {
+      orderBy = $filter(sortFunctionName);
+    };
+
+    /**
+     * Usually when the safe copy is updated the pipe function is called.
+     * Calling this method will prevent it, which is something required when using a custom pipe function
+     */
+    this.preventPipeOnWatch = function preventPipe () {
+      pipeAfterSafeCopy = false;
+    };
+  }])
+  .directive('stTable', function () {
+    return {
+      restrict: 'A',
+      controller: 'stTableController',
+      link: function (scope, element, attr, ctrl) {
+
+        if (attr.stSetFilter) {
+          ctrl.setFilterFunction(attr.stSetFilter);
+        }
+
+        if (attr.stSetSort) {
+          ctrl.setSortFunction(attr.stSetSort);
+        }
+      }
+    };
+  });
+
+ng.module('smart-table')
+  .directive('stSearch', ['stConfig', '$timeout','$parse', function (stConfig, $timeout, $parse) {
+    return {
+      require: '^stTable',
+      link: function (scope, element, attr, ctrl) {
+        var tableCtrl = ctrl;
+        var promise = null;
+        var throttle = attr.stDelay || stConfig.search.delay;
+        var event = attr.stInputEvent || stConfig.search.inputEvent;
+
+        attr.$observe('stSearch', function (newValue, oldValue) {
+          var input = element[0].value;
+          if (newValue !== oldValue && input) {
+            ctrl.tableState().search = {};
+            tableCtrl.search(input, newValue);
+          }
+        });
+
+        //table state -> view
+        scope.$watch(function () {
+          return ctrl.tableState().search;
+        }, function (newValue, oldValue) {
+          var predicateExpression = attr.stSearch || '$';
+          if (newValue.predicateObject && $parse(predicateExpression)(newValue.predicateObject) !== element[0].value) {
+            element[0].value = $parse(predicateExpression)(newValue.predicateObject) || '';
+          }
+        }, true);
+
+        // view -> table state
+        element.bind(event, function (evt) {
+          evt = evt.originalEvent || evt;
+          if (promise !== null) {
+            $timeout.cancel(promise);
+          }
+
+          promise = $timeout(function () {
+            tableCtrl.search(evt.target.value, attr.stSearch || '');
+            promise = null;
+          }, throttle);
+        });
+      }
+    };
+  }]);
+
+ng.module('smart-table')
+  .directive('stSelectRow', ['stConfig', function (stConfig) {
+    return {
+      restrict: 'A',
+      require: '^stTable',
+      scope: {
+        row: '=stSelectRow'
+      },
+      link: function (scope, element, attr, ctrl) {
+        var mode = attr.stSelectMode || stConfig.select.mode;
+        element.bind('click', function () {
+          scope.$apply(function () {
+            ctrl.select(scope.row, mode);
+          });
+        });
+
+        scope.$watch('row.isSelected', function (newValue) {
+          if (newValue === true) {
+            element.addClass(stConfig.select.selectedClass);
+          } else {
+            element.removeClass(stConfig.select.selectedClass);
+          }
+        });
+      }
+    };
+  }]);
+
+ng.module('smart-table')
+  .directive('stSort', ['stConfig', '$parse', '$timeout', function (stConfig, $parse, $timeout) {
+    return {
+      restrict: 'A',
+      require: '^stTable',
+      link: function (scope, element, attr, ctrl) {
+
+        var predicate = attr.stSort;
+        var getter = $parse(predicate);
+        var index = 0;
+        var classAscent = attr.stClassAscent || stConfig.sort.ascentClass;
+        var classDescent = attr.stClassDescent || stConfig.sort.descentClass;
+        var stateClasses = [classAscent, classDescent];
+        var sortDefault;
+        var skipNatural = attr.stSkipNatural !== undefined ? attr.stSkipNatural : stConfig.sort.skipNatural;
+        var descendingFirst = attr.stDescendingFirst !== undefined ? attr.stDescendingFirst : stConfig.sort.descendingFirst;
+        var promise = null;
+        var throttle = attr.stDelay || stConfig.sort.delay;
+
+        if (attr.stSortDefault) {
+          sortDefault = scope.$eval(attr.stSortDefault) !== undefined ? scope.$eval(attr.stSortDefault) : attr.stSortDefault;
+        }
+
+        //view --> table state
+        function sort () {
+          if (descendingFirst) {
+            index = index === 0 ? 2 : index - 1;
+          } else {
+            index++;
+          }
+
+          var func;
+          predicate = ng.isFunction(getter(scope)) || ng.isArray(getter(scope)) ? getter(scope) : attr.stSort;
+          if (index % 3 === 0 && !!skipNatural !== true) {
+            //manual reset
+            index = 0;
+            ctrl.tableState().sort = {};
+            ctrl.tableState().pagination.start = 0;
+            func = ctrl.pipe.bind(ctrl);
+          } else {
+            func = ctrl.sortBy.bind(ctrl, predicate, index % 2 === 0);
+          }
+          if (promise !== null) {
+            $timeout.cancel(promise);
+          }
+          if (throttle < 0) {
+            func();
+          } else {
+            promise = $timeout(func, throttle);
+          }
+        }
+
+        element.bind('click', function sortClick () {
+          if (predicate) {
+            scope.$apply(sort);
+          }
+        });
+
+        if (sortDefault) {
+          index = sortDefault === 'reverse' ? 1 : 0;
+          sort();
+        }
+
+        //table state --> view
+        scope.$watch(function () {
+          return ctrl.tableState().sort;
+        }, function (newValue) {
+          if (newValue.predicate !== predicate) {
+            index = 0;
+            element
+              .removeClass(classAscent)
+              .removeClass(classDescent);
+          } else {
+            index = newValue.reverse === true ? 2 : 1;
+            element
+              .removeClass(stateClasses[index % 2])
+              .addClass(stateClasses[index - 1]);
+          }
+        }, true);
+      }
+    };
+  }]);
+
+ng.module('smart-table')
+  .directive('stPagination', ['stConfig', function (stConfig) {
+    return {
+      restrict: 'EA',
+      require: '^stTable',
+      scope: {
+        stItemsByPage: '=?',
+        stDisplayedPages: '=?',
+        stPageChange: '&'
+      },
+      templateUrl: function (element, attrs) {
+        if (attrs.stTemplate) {
+          return attrs.stTemplate;
+        }
+        return stConfig.pagination.template;
+      },
+      link: function (scope, element, attrs, ctrl) {
+
+        scope.stItemsByPage = scope.stItemsByPage ? +(scope.stItemsByPage) : stConfig.pagination.itemsByPage;
+        scope.stDisplayedPages = scope.stDisplayedPages ? +(scope.stDisplayedPages) : stConfig.pagination.displayedPages;
+
+        scope.currentPage = 1;
+        scope.pages = [];
+
+        function redraw () {
+          var paginationState = ctrl.tableState().pagination;
+          var start = 1;
+          var end;
+          var i;
+          var prevPage = scope.currentPage;
+          scope.totalItemCount = paginationState.totalItemCount;
+          scope.currentPage = Math.floor(paginationState.start / paginationState.number) + 1;
+
+          start = Math.max(start, scope.currentPage - Math.abs(Math.floor(scope.stDisplayedPages / 2)));
+          end = start + scope.stDisplayedPages;
+
+          if (end > paginationState.numberOfPages) {
+            end = paginationState.numberOfPages + 1;
+            start = Math.max(1, end - scope.stDisplayedPages);
+          }
+
+          scope.pages = [];
+          scope.numPages = paginationState.numberOfPages;
+
+          for (i = start; i < end; i++) {
+            scope.pages.push(i);
+          }
+
+          if (prevPage !== scope.currentPage) {
+            scope.stPageChange({newPage: scope.currentPage});
+          }
+        }
+
+        //table state --> view
+        scope.$watch(function () {
+          return ctrl.tableState().pagination;
+        }, redraw, true);
+
+        //scope --> table state  (--> view)
+        scope.$watch('stItemsByPage', function (newValue, oldValue) {
+          if (newValue !== oldValue) {
+            scope.selectPage(1);
+          }
+        });
+
+        scope.$watch('stDisplayedPages', redraw);
+
+        //view -> table state
+        scope.selectPage = function (page) {
+          if (page > 0 && page <= scope.numPages) {
+            ctrl.slice((page - 1) * scope.stItemsByPage, scope.stItemsByPage);
+          }
+        };
+
+        if (!ctrl.tableState().pagination.number) {
+          ctrl.slice(0, scope.stItemsByPage);
+        }
+      }
+    };
+  }]);
+
+ng.module('smart-table')
+  .directive('stPipe', ['stConfig', '$timeout', function (config, $timeout) {
+    return {
+      require: 'stTable',
+      scope: {
+        stPipe: '='
+      },
+      link: {
+
+        pre: function (scope, element, attrs, ctrl) {
+
+          var pipePromise = null;
+
+          if (ng.isFunction(scope.stPipe)) {
+            ctrl.preventPipeOnWatch();
+            ctrl.pipe = function () {
+
+              if (pipePromise !== null) {
+                $timeout.cancel(pipePromise)
+              }
+
+              pipePromise = $timeout(function () {
+                scope.stPipe(ctrl.tableState(), ctrl);
+              }, config.pipe.delay);
+
+              return pipePromise;
+            }
+          }
+        },
+
+        post: function (scope, element, attrs, ctrl) {
+          ctrl.pipe();
+        }
+      }
+    };
+  }]);
+
+})(angular);
\ No newline at end of file
