diff --git a/PythonServer/screens/ts2.py b/PythonServer/screens/ts2.py
index 49488fc6ec9776d62809678bef91342c0316d101..526bae68928f59eaebfa40717104da0dfbd2951f 100755
--- a/PythonServer/screens/ts2.py
+++ b/PythonServer/screens/ts2.py
@@ -9,7 +9,7 @@ class ts2Screen(Thread):
         self.stop_signal = stop_signal
 
     def run(self):
-        pvs = ['CrS-TICP:Cryo-TE-31491:Val', 'TS2-010CDL:Cryo-TE-82313:MeasValue', 'TS2-010CDL:Cryo-TE-82360:MeasValue', 'TS2-010CRM:Cryo-TE-068:MeasValue', 'TS2-010CRM:Cryo-TE-063:MeasValue', 'TS2-010CRM:Cryo-TE-069:MeasValue', 'TS2-010CRM:Cryo-TE-064:MeasValue', 'TS2-010CDL:Cryo-TE-82365:MeasValue', 'TS2-010CDL:Cryo-TE-82314:MeasValue', 'CrS-TICP:Cryo-TE-31492:Val']
+        pvs = ['CrS-TICP:Cryo-TE-31491:Val', 'TS2-010CDL:Cryo-TE-82313:MeasValue', 'TS2-010CDL:Cryo-TE-82360:MeasValue', 'TS2-010CRM:Cryo-TE-068:MeasValue', 'TS2-010CRM:Cryo-TE-063:MeasValue', 'TS2-010CRM:Cryo-TE-069:MeasValue', 'TS2-010CRM:Cryo-TE-064:MeasValue', 'TS2-010CDL:Cryo-TE-82365:MeasValue', 'TS2-010CDL:Cryo-TE-82314:MeasValue', 'CrS-TICP:Cryo-TE-31492:Val', 'TS2-010CRM:Cryo-TE-010:MeasValue', 'TS2-010CRM:Cryo-TE-018:MeasValue', 'TS2-010CRM:Cryo-TE-019:MeasValue', 'TS2-010CRM:Cryo-TE-020:MeasValue', 'TS2-010CRM:Cryo-TE-021:MeasValue', 'TS2-010CRM:Cryo-TE-022:MeasValue', 'TS2-010CRM:Cryo-TE-028:MeasValue', 'TS2-010CRM:Cryo-TE-029:MeasValue', 'TS2-010CRM:Cryo-TE-030:MeasValue', 'TS2-010CRM:Cryo-TE-031:MeasValue', 'TS2-010CRM:Cryo-TE-032:MeasValue', 'TS2-010CRM:Cryo-TE-038:MeasValue', 'TS2-010CRM:Cryo-TE-039:MeasValue', 'TS2-010CRM:Cryo-TE-041:MeasValue', 'TS2-010CRM:Cryo-TE-042:MeasValue', 'TS2-010CRM:Cryo-TE-048:MeasValue', 'TS2-010CRM:Cryo-TE-049:MeasValue']
 
         epics_dict={}
         for pv in pvs:
diff --git a/WebSites/ts2/dashboard.json b/WebSites/ts2/dashboard.json
index 1e83b6998fa5d8790f8bb7e47850061d03e90a14..5ad3955b47b990062012480fce6118afaed14fac 100644
--- a/WebSites/ts2/dashboard.json
+++ b/WebSites/ts2/dashboard.json
@@ -30,221 +30,302 @@
 			]
 		},
 		{
-			"title": "CrS-TICP:Cryo-TE-31491:Val",
+			"title": "Cavity 1",
 			"width": 1,
 			"row": {
-				"4": 7
+				"1": 7,
+				"4": 7,
+				"6": 7,
+				"7": 7
 			},
 			"col": {
-				"4": 1
+				"1": 1,
+				"4": 1,
+				"6": 1,
+				"7": 1
 			},
 			"col_width": 1,
 			"widgets": [
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"CrS-TICP:Cryo-TE-31491:Val\"][\"value\"]",
+						"title": "Cernox in cold tuning system",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-018:MeasValue\"][\"value\"]",
 						"units": "K",
 						"min_value": "0",
 						"max_value": "300"
 					}
-				}
-			]
-		},
-		{
-			"title": "TS2-010CDL:Cryo-TE-82313:MeasValue",
-			"width": 1,
-			"row": {
-				"4": 7
-			},
-			"col": {
-				"4": 2
-			},
-			"col_width": 1,
-			"widgets": [
+				},
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82313:MeasValue\"][\"value\"]",
+						"title": "Cernox in helium tank boTEom",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-019:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
+						"max_value": 300
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Cernox in helium manifold to he tank",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-010:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
 						"max_value": "300"
 					}
 				}
 			]
 		},
 		{
-			"title": "TS2-010CDL:Cryo-TE-82360:MeasValue",
+			"title": "Cavity 2",
 			"width": 1,
 			"row": {
-				"4": 7
+				"1": 27,
+				"4": 7,
+				"7": 7
 			},
 			"col": {
-				"4": 3
+				"1": 1,
+				"4": 2,
+				"7": 2
 			},
 			"col_width": 1,
 			"widgets": [
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82360:MeasValue\"][\"value\"]",
+						"title": "Cernox in cold tuning system - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-028:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
 						"max_value": "300"
 					}
-				}
-			]
-		},
-		{
-			"title": "TS2-010CRM:Cryo-TE-068:MeasValue",
-			"width": 1,
-			"row": {
-				"4": 7
-			},
-			"col": {
-				"4": 4
-			},
-			"col_width": 1,
-			"widgets": [
+				},
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-068:MeasValue\"][\"value\"]",
+						"title": "Cernox in helium tank boTEom",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-029:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
 						"max_value": "300"
 					}
-				}
-			]
-		},
-		{
-			"title": "TS2-010CRM:Cryo-TE-063:MeasValue",
-			"width": 1,
-			"row": {
-				"4": 15
-			},
-			"col": {
-				"4": 1
-			},
-			"col_width": 1,
-			"widgets": [
+				},
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-063:MeasValue\"][\"value\"]",
+						"title": "Cernox in helium manifold to he tank",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-020:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
 						"max_value": "300"
 					}
-				}
-			]
-		},
-		{
-			"title": "TS2-010CRM:Cryo-TE-069:MeasValue",
-			"width": 1,
-			"row": {
-				"4": 15
-			},
-			"col": {
-				"4": 2
-			},
-			"col_width": 1,
-			"widgets": [
+				},
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-069:MeasValue\"][\"value\"]",
+						"title": "PT100 in Power Coupler - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-021:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
 						"max_value": "300"
 					}
-				}
-			]
-		},
-		{
-			"title": "TS2-010CRM:Cryo-TE-064:MeasValue",
-			"width": 1,
-			"row": {
-				"4": 15
-			},
-			"col": {
-				"4": 3
-			},
-			"col_width": 1,
-			"widgets": [
+				},
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-064:MeasValue\"][\"value\"]",
+						"title": "Power Coupler double wall cooling - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-022:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
 						"max_value": "300"
 					}
 				}
 			]
 		},
 		{
-			"title": "TS2-010CDL:Cryo-TE-82365:MeasValue",
+			"title": "Cavity 3",
 			"width": 1,
 			"row": {
-				"4": 15
+				"1": 59,
+				"4": 7,
+				"7": 7
 			},
 			"col": {
-				"4": 4
+				"1": 1,
+				"4": 3,
+				"7": 3
 			},
 			"col_width": 1,
 			"widgets": [
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82365:MeasValue\"][\"value\"]",
+						"title": "Cernox in cold tuning system - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-038:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Cernox in helium tank boTEom",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-039:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Cernox in helium manifold to he tank",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-030:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "PT100 in Power Coupler - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-031:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Power Coupler double wall cooling - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-032:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
 						"max_value": "300"
 					}
 				}
 			]
 		},
 		{
-			"title": "TS2-010CDL:Cryo-TE-82314:MeasValue",
+			"title": "Cavity 4",
 			"width": 1,
 			"row": {
-				"4": 23
+				"1": 91,
+				"4": 7,
+				"7": 7
 			},
 			"col": {
-				"4": 1
+				"1": 1,
+				"4": 4,
+				"7": 4
 			},
 			"col_width": 1,
 			"widgets": [
 				{
 					"type": "gauge",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82314:MeasValue\"][\"value\"]",
+						"title": "Cernox in cold tuning system - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-048:MeasValue\"][\"value\"]",
 						"units": "K",
-						"min_value": "0",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Cernox in helium tank boTEom",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-049:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "PT100 in Power Coupler - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-041:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
+						"max_value": "300"
+					}
+				},
+				{
+					"type": "gauge",
+					"settings": {
+						"title": "Power Coupler double wall cooling - ECCTD only",
+						"value": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-042:MeasValue\"][\"value\"]",
+						"units": "K",
+						"min_value": 0,
 						"max_value": "300"
 					}
 				}
 			]
 		},
 		{
-			"title": "CrS-TICP:Cryo-TE-31492:Val",
-			"width": 1,
+			"title": "Thermal Screens",
+			"width": 4,
 			"row": {
-				"4": 23
+				"4": 39
 			},
 			"col": {
-				"4": 2
+				"4": 1
 			},
-			"col_width": 1,
+			"col_width": 4,
 			"widgets": [
 				{
-					"type": "gauge",
+					"type": "highcharts-timeseries",
 					"settings": {
-						"value": "datasources[\"TS2\"][\"CrS-TICP:Cryo-TE-31492:Val\"][\"value\"]",
-						"units": "K",
-						"min_value": "0",
-						"max_value": "300"
+						"timeframe": 60,
+						"blocks": 4,
+						"chartType": "spline",
+						"xaxis": "{\"title\":{\"text\" : \"Time\"}, \"type\": \"datetime\", \"floor\":0}",
+						"yaxis": "{\"title\":{\"text\" : \"Values\"}, \"minorTickInterval\":\"auto\", \"floor\":0}",
+						"series1": "datasources[\"TS2\"][\"CrS-TICP:Cryo-TE-31491:Val\"][\"value\"]",
+						"series1label": "CrS-TICP:Cryo-TE-31491",
+						"series2": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82313:MeasValue\"][\"value\"]",
+						"series2label": "TS2-010CDL:Cryo-TE-82313",
+						"series3": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82360:MeasValue\"][\"value\"]",
+						"series3label": "TS2-010CDL:Cryo-TE-82360"
+					}
+				},
+				{
+					"type": "highcharts-timeseries",
+					"settings": {
+						"timeframe": 60,
+						"blocks": 4,
+						"chartType": "spline",
+						"xaxis": "{\"title\":{\"text\" : \"Time\"}, \"type\": \"datetime\", \"floor\":0}",
+						"yaxis": "{\"title\":{\"text\" : \"Values\"}, \"minorTickInterval\":\"auto\", \"floor\":0}",
+						"series1": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-068:MeasValue\"][\"value\"]",
+						"series1label": "TS2-010CRM:Cryo-TE-068",
+						"series2": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-064:MeasValue\"][\"value\"]",
+						"series2label": "TS2-010CRM:Cryo-TE-064",
+						"series3": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-069:MeasValue\"][\"value\"]",
+						"series3label": "TS2-010CRM:Cryo-TE-069"
+					}
+				},
+				{
+					"type": "highcharts-timeseries",
+					"settings": {
+						"timeframe": 60,
+						"blocks": 4,
+						"chartType": "spline",
+						"xaxis": "{\"title\":{\"text\" : \"Time\"}, \"type\": \"datetime\", \"floor\":0}",
+						"yaxis": "{\"title\":{\"text\" : \"Values\"}, \"minorTickInterval\":\"auto\", \"floor\":0}",
+						"series1": "datasources[\"TS2\"][\"TS2-010CRM:Cryo-TE-064:MeasValue\"][\"value\"]",
+						"series1label": "TS2-010CRM:Cryo-TE-064",
+						"series2": "datasources[\"TS2\"][\"TS2-010CDL:Cryo-TE-82314:MeasValue\"][\"value\"]",
+						"series2label": "TS2-010CDL:Cryo-TE-82314",
+						"series3": "datasources[\"TS2\"][\"CrS-TICP:Cryo-TE-31492:Val\"][\"value\"]",
+						"series3label": "CrS-TICP:Cryo-TE-31492:Val"
 					}
 				}
 			]
@@ -257,7 +338,7 @@
 			"settings": {
 				"url": "/data/ts2.json",
 				"use_thingproxy": false,
-				"refresh": 1,
+				"refresh": 5,
 				"method": "GET"
 			}
 		}
diff --git a/WebSites/ts2/index.html b/WebSites/ts2/index.html
index b64a5da74bdbe2f0464cd0178bf6155a3f33f7a4..80f75326bfb89bba6f54a3de18fc0b7b996b4260 100644
--- a/WebSites/ts2/index.html
+++ b/WebSites/ts2/index.html
@@ -46,6 +46,8 @@
                 "plugins/freeboard/freeboard.widgets.js",
 		"plugins/thirdparty/flot_extended.plugin.js",
 		"plugins/thirdparty/widget.ragIndicator.js",
+    "plugins/thirdparty/horizontal_linear_gauge.widgets.js",
+    "plugins/thirdparty/plugin_highcharts.js",
 		"SlickNav/dist/jquery.slicknav.min.js",
                 "examples/plugin_example.js",
 
diff --git a/WebSites/ts2/plugins/thirdparty/horizontal_linear_gauge.widgets.js b/WebSites/ts2/plugins/thirdparty/horizontal_linear_gauge.widgets.js
new file mode 100644
index 0000000000000000000000000000000000000000..5eb846aaaed677f15a061573f1b196dacea58392
--- /dev/null
+++ b/WebSites/ts2/plugins/thirdparty/horizontal_linear_gauge.widgets.js
@@ -0,0 +1,194 @@
+//
+// Plugin for horizontal linear gauge
+//
+//
+
+(function() {
+    var gaugeWidget = function (settings) {
+        var titleElement = $('<h2 class="section-title"></h2>');
+        var gaugeElement = $('<div></div>');
+
+        var self = this;
+        var paper = null;
+        var gaugeFill = null;
+        var width, height;
+        var valueText, unitsText;
+        var minValueLabel, maxValueLabel;
+        //var currentValue = 0;
+        //var colors = ["#a9d70b", "#f9c802", "#ff0000"];
+
+        var currentSettings = settings;
+
+        /* get the color for a fill percentage
+           these colors match the justGage library for radial guagues */
+        function getColor(fillPercent) {
+            // mix colors
+            // green rgb(169,215,11) #a9d70b
+            // yellow rgb(249,200,2) #f9c802
+            // red rgb(255,0,0) #ff0000
+
+            if (fillPercent >= 0.5 ) {
+                fillPercent = 2 * fillPercent - 1;
+                var R = fillPercent * 255 + (1 - fillPercent) * 249;
+                var G = fillPercent * 0 + (1 - fillPercent) * 200;
+                var B = fillPercent * 0 + (1 - fillPercent) * 2;
+            }
+            else {
+                fillPercent = 2 * fillPercent;
+                var R = fillPercent * 249 + (1 - fillPercent) * 169;
+                var G = fillPercent * 200 + (1 - fillPercent) * 215;
+                var B = fillPercent * 2 + (1 - fillPercent) * 11;
+            }
+
+            return "rgb(" + Math.round(R) + "," + Math.round(G) + "," + Math.round(B) + ")"
+        }
+
+        self.render = function (element) {
+            $(element).append(titleElement.html(currentSettings.title)).append(gaugeElement);
+
+            width = gaugeElement.width();
+            height = 160;
+
+            var gaugeWidth = 160;
+            var gaugeHeight = 30;
+
+            paper = Raphael(gaugeElement.get()[0], width, height);
+            paper.clear();
+
+            var rect = paper.rect(width / 2 - gaugeWidth / 2, height / 3 - gaugeHeight / 2, gaugeWidth, gaugeHeight);
+            rect.attr({
+                "fill": "#edebeb",
+                "stroke": "#edebeb"
+            });
+
+            // place min and max labels
+            minValueLabel = paper.text(width / 2 - gaugeWidth / 2 - 8, height / 3, currentSettings.min_value);
+            maxValueLabel = paper.text(width / 2 + gaugeWidth / 2 + 8, height / 3, currentSettings.max_value);
+
+            minValueLabel.attr({
+                "font-family": "arial",
+                "font-size": "10",
+                "fill": "#b3b3b3",
+                "text-anchor": "end"
+            });
+
+            maxValueLabel.attr({
+                "font-family": "arial",
+                "font-size": "10",
+                "fill": "#b3b3b3",
+                "text-anchor": "start"
+            });
+
+            // place units and value
+            var units = _.isUndefined(currentSettings.units) ? "" : currentSettings.units;
+
+            valueText = paper.text(width / 2, height * 2 / 3, "");
+            unitsText = paper.text(width / 2, height * 2 / 3 + 20, units);
+
+            valueText.attr({
+                "font-family": "arial",
+                "font-size": "25",
+                "font-weight": "bold",
+                "fill": "#d3d4d4",
+                "text-anchor": "middle"
+            });
+
+            unitsText.attr({
+                "font-family": "arial",
+                "font-size": "10",
+                "font-weight": "normal",
+                "fill": "#b3b3b3",
+                "text-anchor": "middle"
+            });
+
+            // fill to 0 percent
+            gaugeFill = paper.rect(width / 2 - gaugeWidth / 2, height / 3 - gaugeHeight / 2, 0, gaugeHeight);
+        }
+
+        self.onSettingsChanged = function (newSettings) {
+            if (newSettings.units != currentSettings.units || newSettings.min_value != currentSettings.min_value || newSettings.max_value != currentSettings.max_value) {
+                currentSettings = newSettings;
+                var units = _.isUndefined(currentSettings.units) ? "" : currentSettings.units;
+                var min = _.isUndefined(currentSettings.min_value) ? 0 : currentSettings.min_value;
+                var max = _.isUndefined(currentSettings.max_value) ? 0 : currentSettings.max_value;
+
+                unitsText.attr({"text": units});
+                minValueLabel.attr({"text": min});
+                maxValueLabel.attr({"text": max});
+            }
+            else {
+                currentSettings = newSettings;
+            }
+
+            titleElement.html(newSettings.title);
+        }
+
+        self.onCalculatedValueChanged = function (settingName, newValue) {
+            if (settingName === "value") {
+                if (!_.isUndefined(gaugeFill) && !_.isUndefined(valueText)) {
+
+                    newValue = _.isUndefined(newValue) ? 0 : newValue;
+                    var fillVal = 160 * (newValue - currentSettings.min_value)/(currentSettings.max_value - currentSettings.min_value);
+
+                    fillVal = fillVal > 160 ? 160 : fillVal;
+                    fillVal = fillVal < 0 ? 0 : fillVal;
+
+                    var fillColor = getColor(fillVal / 160);
+
+                    gaugeFill.animate({"width": fillVal, "fill": fillColor, "stroke": fillColor}, 500, ">");
+                    valueText.attr({"text": newValue});
+                }
+            }
+        }
+
+        self.onDispose = function () {
+        }
+
+        self.getHeight = function () {
+            return 3;
+        }
+
+    };
+
+    freeboard.loadWidgetPlugin({
+        type_name: "horizontal-linear-gauge",
+        display_name: "Horizontal Linear Gauge",
+        "external_scripts" : [
+         "plugins/thirdparty/raphael.2.1.0.min.js",
+         //   "plugins/thirdparty/raphael.2.1.0-custom.js",
+        "plugins/thirdparty/colormix.2.0.0.min.js"
+        ],
+        settings: [
+            {
+                name: "title",
+                display_name: "Title",
+                type: "text"
+            },
+            {
+                name: "value",
+                display_name: "Value",
+                type: "calculated"
+            },
+            {
+                name: "units",
+                display_name: "Units",
+                type: "text"
+            },
+            {
+                name: "min_value",
+                display_name: "Minimum",
+                type: "number",
+                default_value: 0
+            },
+            {
+                name: "max_value",
+                display_name: "Maximum",
+                type: "number",
+                default_value: 100
+            }
+        ],
+        newInstance: function (settings, newInstanceCallback) {
+            newInstanceCallback(new gaugeWidget(settings));
+        }
+    });
+}());
diff --git a/WebSites/ts2/plugins/thirdparty/plugin_highcharts.js b/WebSites/ts2/plugins/thirdparty/plugin_highcharts.js
new file mode 100644
index 0000000000000000000000000000000000000000..d36c89d792e9a6b0d0a079c344a9f23a17738082
--- /dev/null
+++ b/WebSites/ts2/plugins/thirdparty/plugin_highcharts.js
@@ -0,0 +1,458 @@
+// ┌────────────────────────────────────────────────────────────────────┐ \\
+// │ freeboard-dynamic-highcharts-plugin                                │ \\
+// ├────────────────────────────────────────────────────────────────────┤ \\
+// │ http://blog.onlinux.fr/dynamic-highcharts-plugin-for-freeboard-io/ │ \\
+// ├────────────────────────────────────────────────────────────────────┤ \\
+// │ Licensed under the MIT license.                                    │ \\
+// ├────────────────────────────────────────────────────────────────────┤ \\
+// │ Freeboard widget plugin for Highcharts.                            │ \\
+// └────────────────────────────────────────────────────────────────────┘ \\
+(function() {
+
+	//
+	// DECLARATIONS
+	//
+	var HIGHCHARTS_ID = 0;
+	var ONE_SECOND_IN_MILIS = 1000;
+	var MAX_NUM_SERIES = 3;
+
+	//
+	// HELPERS
+	//
+
+	// Get coordinates of point
+	function xy(obj, x, y) {
+		return [obj[x], obj[y]]
+	}
+
+	function isNumber(n) {
+		return !isNaN(parseFloat(n)) && isFinite(n);
+	}
+	//
+	// TIME SERIES CHARTS
+	//
+	var highchartsLineWidgetSettings = [{
+		"name": "timeframe",
+		"display_name": "Timeframe (s)",
+		"type": "number",
+		"description": "Specify the last number of seconds you want to see.",
+		"default_value": 60
+	}, {
+		"name": "blocks",
+		"display_name": "Height (No. Blocks)",
+		"type": "number",
+		"default_value": 4
+	}, {
+		"name": "chartType",
+		"display_name": "Chart Type",
+		"type": "option",
+		"options": [{
+			"name": "Area",
+			"value": "area"
+		}, {
+			"name": "Spline",
+			"value": "spline"
+		}]
+	}, {
+		"name": "title",
+		"display_name": "Title",
+		"type": "text"
+	}, {
+		"name": "xaxis",
+		"display_name": "X-Axis",
+		"type": "calculated",
+		"default_value": "{\"title\":{\"text\" : \"Time\"}, \"type\": \"datetime\", \"floor\":0}"
+	}, {
+		"name": "yaxis",
+		"display_name": "Y-Axis",
+		"type": "calculated",
+		"default_value": "{\"title\":{\"text\" : \"Values\"}, \"minorTickInterval\":\"auto\", \"floor\":0}"
+	}];
+
+	for (i = 1; i <= MAX_NUM_SERIES; i++) {
+		var dataSource = {
+			"name": "series" + i,
+			"display_name": "Series " + i + " - Datasource",
+			"type": "calculated"
+		};
+
+		var xField = {
+			"name": "series" + i + "label",
+			"display_name": "Series " + i + " - Label",
+			"type": "text",
+		};
+
+		highchartsLineWidgetSettings.push(dataSource);
+		highchartsLineWidgetSettings.push(xField);
+	}
+
+	freeboard
+		.loadWidgetPlugin({
+			"type_name": "highcharts-timeseries",
+			"display_name": "Time series (Highcharts)",
+			"description": "Time series line chart.",
+			"external_scripts": [
+				"https://code.highcharts.com/highcharts.js",
+				"https://code.highcharts.com/modules/exporting.js"
+			],
+			"fill_size": true,
+			"settings": highchartsLineWidgetSettings,
+			newInstance: function(settings, newInstanceCallback) {
+				newInstanceCallback(new highchartsTimeseriesWidgetPlugin(
+					settings));
+			}
+		});
+
+	var highchartsTimeseriesWidgetPlugin = function(settings) {
+
+		var self = this;
+		var currentSettings = settings;
+
+		var thisWidgetId = "highcharts-widget-timeseries-" + HIGHCHARTS_ID++;
+		var thisWidgetContainer = $('<div class="highcharts-widget" id="' + thisWidgetId + '"></div>');
+
+		function createWidget() {
+
+			Highcharts.theme = {
+				global: {
+					useUTC: false
+				},
+				colors: ["#2b908f", "#90ee7e", "#f45b5b", "#7798BF", "#aaeeee",
+					"#ff0066", "#eeaaee", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"
+				],
+				chart: {
+					backgroundColor: null,
+					style: {
+						fontFamily: "'Open Sans', sans-serif"
+					},
+					plotBorderColor: '#606063'
+				},
+                                plotShadow: false,
+				title: {
+					style: {
+						color: '#E0E0E3',
+						fontSize: '20px'
+					}
+				},
+				subtitle: {
+					style: {
+						color: '#E0E0E3',
+						textTransform: 'uppercase'
+					}
+				},
+				xAxis: {
+					gridLineColor: '#707073',
+					labels: {
+						style: {
+							color: '#E0E0E3'
+						}
+					},
+					lineColor: '#707073',
+					minorGridLineColor: '#505053',
+					tickColor: '#707073',
+					title: {
+						style: {
+							color: '#A0A0A3'
+
+						}
+					}
+				},
+				yAxis: {
+					gridLineColor: '#707073',
+					labels: {
+						style: {
+							color: '#E0E0E3'
+						}
+					},
+					lineColor: '#707073',
+					minorGridLineColor: '#505053',
+					tickColor: '#707073',
+					tickWidth: 1,
+					title: {
+						style: {
+							color: '#A0A0A3'
+						}
+					}
+				},
+				tooltip: {
+					backgroundColor: 'rgba(0, 0, 0, 0.85)',
+					style: {
+						color: '#F0F0F0'
+					}
+				},
+				plotOptions: {
+					series: {
+						dataLabels: {
+							color: '#B0B0B3'
+						},
+						marker: {
+							lineColor: '#333'
+						}
+					},
+					boxplot: {
+						fillColor: '#505053'
+					},
+					candlestick: {
+						lineColor: 'white'
+					},
+					errorbar: {
+						color: 'white'
+					}
+				},
+				legend: {
+					itemStyle: {
+						color: '#E0E0E3'
+					},
+					itemHoverStyle: {
+						color: '#FFF'
+					},
+					itemHiddenStyle: {
+						color: '#606063'
+					}
+				},
+				credits: {
+                                        enabled: false,
+					style: {
+						color: '#666'
+					}
+				},
+				labels: {
+					style: {
+						color: '#707073'
+					}
+				},
+
+				drilldown: {
+					activeAxisLabelStyle: {
+						color: '#F0F0F3'
+					},
+					activeDataLabelStyle: {
+						color: '#F0F0F3'
+					}
+				},
+
+				navigation: {
+					buttonOptions: {
+						symbolStroke: '#DDDDDD',
+						theme: {
+							fill: '#505053'
+						}
+					}
+				},
+
+				// scroll charts
+				rangeSelector: {
+					buttonTheme: {
+						fill: '#505053',
+						stroke: '#000000',
+						style: {
+							color: '#CCC'
+						},
+						states: {
+							hover: {
+								fill: '#707073',
+								stroke: '#000000',
+								style: {
+									color: 'white'
+								}
+							},
+							select: {
+								fill: '#000003',
+								stroke: '#000000',
+								style: {
+									color: 'white'
+								}
+							}
+						}
+					},
+					inputBoxBorderColor: '#505053',
+					inputStyle: {
+						backgroundColor: '#333',
+						color: 'silver'
+					},
+					labelStyle: {
+						color: 'silver'
+					}
+				},
+
+				navigator: {
+					handles: {
+						backgroundColor: '#666',
+						borderColor: '#AAA'
+					},
+					outlineColor: '#CCC',
+					maskFill: 'rgba(255,255,255,0.1)',
+					series: {
+						color: '#7798BF',
+						lineColor: '#A6C7ED'
+					},
+					xAxis: {
+						gridLineColor: '#505053'
+					}
+				},
+
+				scrollbar: {
+					barBackgroundColor: '#808083',
+					barBorderColor: '#808083',
+					buttonArrowColor: '#CCC',
+					buttonBackgroundColor: '#606063',
+					buttonBorderColor: '#606063',
+					rifleColor: '#FFF',
+					trackBackgroundColor: '#404043',
+					trackBorderColor: '#404043'
+				},
+
+				// special colors for some of the
+				legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
+				background2: '#505053',
+				dataLabelsColor: '#B0B0B3',
+				textColor: '#C0C0C0',
+				contrastTextColor: '#F0F0F3',
+				maskColor: 'rgba(255,255,255,0.3)'
+			};
+
+			Highcharts.setOptions(Highcharts.theme);
+
+			// Get widget configurations
+			var thisWidgetXAxis = JSON.parse(currentSettings.xaxis);
+			var thisWidgetYAxis = JSON.parse(currentSettings.yaxis);
+			var thisWidgetTitle = currentSettings.title;
+			var thisWidgetChartType = currentSettings.chartType;
+			//console.log('chartType:' + currentSettings.chartType + ' ' + thisWidgetChartType);
+			var thisWidgetSeries = [];
+
+			for (i = 1; i <= MAX_NUM_SERIES; i++) {
+				var datasource = currentSettings['series' + i];
+				if (datasource) {
+					var serieno = "series" + i + "label";
+					var label = currentSettings[serieno];
+					console.log('label: ', label);
+					var newSeries = {
+						id: 'series' + i,
+						name: label,
+						fillColor: {
+							linearGradient: {
+								x1: 0,
+								y1: 0,
+								x2: 0,
+								y2: 1
+							},
+							stops: [
+								[0, Highcharts.getOptions().colors[i - 1]],
+								//[1, 'rgba(2,0,0,0)']
+								[1, Highcharts.Color(Highcharts.getOptions().colors[i - 1]).setOpacity(0).get('rgba')]
+							]
+						},
+
+						data: [],
+						connectNulls: true
+					};
+					
+					thisWidgetSeries.push(newSeries);
+				}
+			}
+
+			// Create widget
+			thisWidgetContainer
+				.css('height', 60 * self.getHeight() - 10 + 'px');
+			thisWidgetContainer.css('width', '100%');
+
+			thisWidgetContainer.highcharts({
+				chart: {
+					type: thisWidgetChartType,
+					animation: Highcharts.svg,
+					marginRight: 20
+				},
+				title: {
+					text: thisWidgetTitle
+				},
+				xAxis: thisWidgetXAxis,
+				yAxis: thisWidgetYAxis,
+
+				plotOptions: {
+					area: {
+						marker: {
+							enabled: false,
+							symbol: 'circle',
+							radius: 2,
+							hover: {
+								enabled: true
+							}
+						},
+						lineWidth: 2,
+						states: {
+							hover: {
+								lineWidth: 2
+							}
+						},
+						threshold: null
+					}
+				},
+
+				tooltip: {
+					formatter: function() {
+						return '<b>' + this.series.name + '</b><br/>' + Highcharts.dateFormat('%Y-%m-%d %H:%M:%S',
+							this.x) + '<br/>' + Highcharts.numberFormat(this.y, 1);
+					}
+				},
+				series: thisWidgetSeries
+			});
+		}
+
+		self.render = function(containerElement) {
+			$(containerElement).append(thisWidgetContainer);
+			createWidget();
+		}
+
+		self.getHeight = function() {
+			return currentSettings.blocks;
+		}
+
+		self.onSettingsChanged = function(newSettings) {
+			currentSettings = newSettings;
+			createWidget();
+		}
+
+		self.onCalculatedValueChanged = function(settingName, newValue) {
+			// console.log(settingName, 'newValue:', newValue);
+
+			var chart = thisWidgetContainer.highcharts();
+			var series = chart.get(settingName);
+			if (series) {
+				var timeframeMS = currentSettings.timeframe * ONE_SECOND_IN_MILIS;
+				var seriesno = settingName;
+				var len = series.data.length;
+				var shift = false;
+
+				// Check if it should shift the series
+				if (series.data.length > 1) {
+
+					var first = series.data[0].x;
+					//var last = series.data[series.data.length-1].x;
+					var last = new Date().getTime();
+					// Check if time frame is complete
+					var diff = last - first;
+					//                                         console.log('last :', last);
+					//                                         console.log('first:', first);
+					//                                         console.log('diff :', diff);
+
+					if (last - first > timeframeMS) {
+						shift = true;
+					}
+				}
+
+				if (isNumber(newValue)) { //check if it is a real number and not text
+					var x = (new Date()).getTime();
+					// console.log('addPoint:', x,currentSettings[seriesno], Number(newValue));
+					var plotMqtt = [x, Number(newValue)]; //create the array+ "Y"
+					series.addPoint(plotMqtt, true, shift);
+				};
+			}
+		}
+
+		self.onDispose = function() {
+			return;
+		}
+	}
+
+}());