tempStats.html HTML Source View



<!!DOCTYPE html>>
<html>
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
	<link rel="icon" type="image/png" href="favicon196.png" sizes="196x196">
	<link rel="stylesheet" href="styles/jquery.mobile-1.0b2.min.css" />
	<link rel="stylesheet" href="styles/eth.css" />
	<script src="styles/jquery-1.6.4.min.js" type="text/javascript"></script> 
	<script src="styles/jquery.mobile-1.0b2.min.js" type="text/javascript"></script> 
	<script src="styles/highcharts-custom.js" type="text/javascript"></script> 
			<script type="text/javascript" src="styles/jquery.mobile.simpledialog.min.js"></script> 
	<link rel="stylesheet" type="text/css" href="styles/jquery.mobile.simpledialog.min.css" />
<style>	.ui-checkbox {		display:inline-block;	}
			.inline-datepicker {
			width: 140px; padding: .4em;
    line-height: 1.4;    font-size: 16px;    display: inline; vertical-align:top; margin-top: 7px;
		}
	</style> 
</head>
<body>
	<div data-role="page" id="tempStatTopPage" data-title="Temperature Chart - Wireless Tags">

		<div data-role="header" data-theme="b" data-position="inline">
			<a href="javascript:closeGraph();" data-icon="delete" data-iconpos="notext" data-ajax="false">Close</a>
			<a class="ui-btn-right" id="top_right_btn" data-icon="share" data-ajax=0 data-theme="b">Share</a>
		</div>
		<div id="tempStatGraphs" style="width: 100%; ">
		</div>
		<center>
			<span class="loggedInOnly"><button data-icon="arrow-d" data-inline=1 data-theme="b" id="downloadTemperatureLogBtn">Download CSV</button></span>
			<input type="checkbox" name="since_calibration" id="since_calibration" class="custom" /><label for="since_calibration">Show since last calibration</label>
			<input type="checkbox" name="hourly_minmax" id="hourly_minmax" class="custom" /><label for="hourly_minmax">Show hourly highs &amp; lows</label>
			<span class="loggedInOnly"><button data-icon="delete" data-inline=1 data-theme="e" id="deleteTemperatureLogBtn">Delete temperature log</button></span>
			<input type="date" name="custom_min" id="custom_min" class="inline-datepicker ui-body-null ui-corner-all ui-shadow-inset ui-body-c" />
			<input type="date" name="custom_max" id="custom_max" class="inline-datepicker ui-body-null ui-corner-all ui-shadow-inset ui-body-c" />

			<button data-icon="search" data-inline=1 data-theme="b" id="zoomBtn">Zoom To</button>
			<button data-icon="arrow-r" data-inline=1 data-theme="c" onclick="location.replace('tempStatsDaily.html'+window.location.search)">View daily graph</button>
		</center>
		<center class="sharedOnly">
			Captured by <a href="http://wirelesstag.net">Wireless Sensor Tags</a>
		</center>
	<script src="styles/client.js" type="text/javascript"></script> 
	<script src="styles/rawDataChart.js" type="text/javascript"></script> 
	<script type="text/javascript">
		var params = (window.location.search.length > 0 ? window.location.search.substring(1) : localStorage["mytaglist.stats.slaveid"]).split('&');
		var slaveId = params[0];
		var tagName = params.length > 1 ? decodeURIComponent(params[1]) : localStorage["mytaglist.stats.name"];
		var isUUID = slaveId.length > 4;
		if (!tagName && params.length > 1 && isUUID) tagName = decodeURIComponent(params[1]);
		var temp_unit = params.length > 2 ? (params[2] == "F" ? 1 : 0) : -1;

		var since_calibration = localStorage["mytaglist.since_calibration"] == "true";
		var hourly_minmax = localStorage["mytaglist.hourly_minmax"] == "true";
		var hasALS = window.location.search.length > 0 ? params.length>3 : localStorage["mytaglist.stats.hasALS"] == "true";
		if (hasALS) dewPointMode = true;

		$("#since_calibration").attr("checked", since_calibration);
		$("#hourly_minmax").attr("checked", hourly_minmax);
		$("#since_calibration").change(function () {
			since_calibration = localStorage["mytaglist.since_calibration"] = this.checked ? "true" : "false";
			statData = null;
			clearHourlyData();
			loadFirstData();
		});
		$("#hourly_minmax").change(function () {
			hourly_minmax = localStorage["mytaglist.hourly_minmax"] = this.checked ? "true" : "false";
			if (hourly_minmax)
				location.reload();
			else {
				tempMinMaxChartSeries.remove(false);
				if (capMinMaxChartSeries) capMinMaxChartSeries.remove(true);
				if (luxMinMaxChartSeries) luxMinMaxChartSeries.remove(true);
			}
		});

		function resizeChart() {
			holder.highcharts().setSize(
			   $(window).width(),
			   $(window).height() - 42,
			   false
			);
		}
		var holder = $("#tempStatGraphs");
		$(window).resize(function () {
			resizeChart();
		});
		
		var shareInfo;
		if (window.location.search.length > 0) {
			$(".loggedInOnly").hide();
			$(".sharedOnly").show();

			var btn = $("#top_right_btn");
			btn.data("icon", "arrow-d");
			btn[0].innerHTML = "Download";
			btn.click(function () {
				window.location = WSROOT + "ethDownloadTempCSV.aspx?uuid=" + params[0] + "&name=" + tagName + "&fromDate=" + $("#custom_min").val() + "&toDate=" + $("#custom_max").val();
			});
		} else {
			$(".sharedOnly").hide();
			$("#downloadTemperatureLogBtn").click(function () {
				window.location = WSROOT + "ethDownloadTempCSV.aspx?id=" + params[0] + "&fromDate=" + $("#custom_min").val() + "&toDate=" + $("#custom_max").val();
			});
			$("#top_right_btn").click(function () {
				var btn2 = $("#top_right_btn").find(".ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Loading...");
				$.ajax({
					url: WSROOT + "ethLogs.asmx/GetSharePermissions",
					data: JSON.stringify({ "ids": [slaveId], "type": "temperature"}),
					complete: function () { restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						shareInfo = retval.d;

						var html = "<div style='padding: 15px; width: "+(window.innerWidth-200)+"px'><b>Share this data</b>"+
						"<div data-role='fieldcontain'><label for='graphURL'>Link to open graph in Web:</label><input type='text' id='graphURL'></div>"+
						"<div data-role='fieldcontain'><label for='downloadURL'>CSV download link:</label><input type='text' id='downloadURL'></div>"+
						"<div data-role='fieldcontain'><label for='iosURL'>Link to open graph in iOS app:</label><input type='text' id='iosURL'></div>"+
						"<form><center><input type='checkbox' id='shareTemp'><label for='shareTemp'>Anyone with link can access temperature data for this tag</label> " +
						"<input type='checkbox' id='shareMotion'><label for='shareMotion'>Anyone with link can access motion log data for this tag</label>"+
						"<a rel='close' data-role='button' data-inline=1 data-theme='b' data-icon='check' href='#'>Apply Permissions</a></center></form></div>";

						if (holder.data('simpledialog')) {
							holder.data('simpledialog').options.fullHTML = html;
							holder.simpledialog('refresh').simpledialog('open');
						} else {
							holder.simpledialog({
								'mode': 'blank',
								'left': 80 ,'top':'0px',
								'prompt': false,
								'forceInput': false,
								'useModal': true,
								pickPageTheme: 'c',
								'fullHTML': html,
								onClosed: function () {
									if (shareInfo.shareMotion[0] != $("#shareMotion").is(":checked") || shareInfo.shareTemperature[0] != $("#shareTemp").is(":checked")) {
										$.ajax({
											url: WSROOT + "ethLogs.asmx/EditSharePermissions",
											data: JSON.stringify({ "ids": [slaveId], "shareTemperature": [$("#shareTemp").is(":checked")], "shareMotion":[$("#shareMotion").is(":checked")] }),
											error: function (xhr, textStatus, exception) {
												popup_error(xhr, null);
											}
										});
									}
								}
							});
						}

						$("#shareMotion").attr("checked", shareInfo.shareMotion[0]).checkboxradio("refresh");
						$("#shareTemp").attr("checked", shareInfo.shareTemperature[0]).checkboxradio("refresh");
						$("#graphURL").val(shareInfo.graphUrl).click(function () { return selectedURL(this, false); });
						$("#downloadURL").val(shareInfo.downloadUrl).click(function () { return selectedURL(this, false); });
						$("#iosURL").val(shareInfo.iosAppUrl).click(function () { return selectedURL(this, false); });
						$("#embedHTML").val(shareInfo.embedHTML).click(function () { return selectedURL(this, false); });
	},
	error: function (xhr, textStatus, exception) {
		popup_error(xhr, null);
	}
	});
	});
	}

	var $loader = $("<div class='ui-loader ui-body-a ui-corner-all'><span class='ui-icon ui-icon-loading spin'></span><h1>Loading Data...</h1></div>");
	$body = $("body");

	function ajaxErrorHandler(xhr, exception) {
		if (xhr.responseText.toLowerCase().indexOf("unauthorized") != -1 || exception.toLowerCase().indexOf("unauthorized") != -1 || xhr.responseText.toLowerCase().indexOf("authentication failed") != -1)
			location.replace("signin.html?ReturnUrl=" + encodeURIComponent(window.location.pathname + window.location.search));
		else {
			$loader.remove();
			popup_error(xhr, $body);
		}
	}


	$loader.appendTo($body).css({ top: 100 });
	$body.addClass("ui-loading");

	var tempSeries = [], tempMinMaxSeries=[];
	var capSeries = [], capMinMaxSeries=[];
	var luxSeries=[], luxMinMaxSeries=[];
	var bandCapSeries = [];
	var bandTempSeries = [];
	var bandLuxSeries=[];
	var rawTempSeries = [];
	var rawCapSeries = [];
	var rawLuxSeries = [];

	var capChartSeries = null, tempMinMaxChartSeries = null, capMinMaxChartSeries = null;
	var luxChartSeries = null, luxMinMaxChartSeries = null;
	var tzoffset = (new Date()).getTimezoneOffset() * 60000;
	function createLuxAxis() {
		chart.addAxis({
			gridLineWidth: 0,
			title: { text: "Lux", style: { color: luxColor } },
			labels: { style: { color: luxColor } },
			opposite: true
			,type: "logarithmic"
		});
		luxChartSeries = chart.addSeries({
			name: "Ambient Light", yAxis: 1,
			tooltip: { valueSuffix: " lux" }, color: luxColor
		});
		if (hourly_minmax) {
			luxMinMaxChartSeries = chart.addSeries({
				name: "Ambient Light Highs/Lows", yAxis: 1,
				tooltip: { valueSuffix: " lux" },
				color: luxRangeColor, visible: false
			});
		}
	}
	function createCapAxis() {
		if (!dewPointMode) {
			chart.addAxis({ // Secondary yAxis
				gridLineWidth: 0,
				title: {
					text: 'Humidity', style: { color: capColor }
				},
				labels: {
					format: '{value} %', style: { color: capColor }
				},
				opposite: true
			});
		}
		capChartSeries = chart.addSeries({
			name: dewPointMode ? 'Dew Point' : 'Humidity',
			yAxis: dewPointMode ? 0 : 1,
			tooltip: {
				valueSuffix: dewPointMode ? " °" + (temp_unit == 1 ? "F" : "C") : " %"
			},
			color: capColor
		});
		if (hourly_minmax) {
			capMinMaxChartSeries = chart.addSeries({
				name: dewPointMode ? 'Dew Point Highs/Lows' : 'Humidity Highs/Lows', turboThreshold: 1e6,
				yAxis: dewPointMode ? 0 : 1,
				tooltip: {
					valueSuffix: dewPointMode ? " °" + (temp_unit == 1 ? "F" : "C") : " %"
				},
				color: capRangeColor, visible: false
			});
		}
	}
	function translateCapVal(val, temp) {
		if (dewPointMode) {
			val = dewPoint(val, temp);
			if (temp_unit == 1) val = val * 9.0 / 5.0 + 32.0;
		}
		return val;
	}
	function translateTempVal(val){
		return temp_unit==1? val* 9.0 / 5.0 + 32.0 : val;
	}
		// baseDate is Date.parse(date_string)
	function processOneDay(day, baseDate, prepend) {
		var avg = 0;
		var tods = day.tods;
		var count = tods ? tods.length : 24;
		var capMin = 100, capMax = 0, tempMin = temp_unit == 1 ? 220 : 115, tempMax = temp_unit == 1 ? -28.0 : -40.0;
		var luxMin = 80000, luxMax = 0;
		if (dewPointMode) { capMin = tempMin; capMax = -100;}
		for (var i = 0; i < count; i++) {
			var n = prepend ? count - i - 1 : i;
			if (day.caps[n] != -99) {

				if (capChartSeries==null) createCapAxis();

				var dataPoint = [baseDate + (tods ? tods[n] * 1000 : HOUR * (n+0.5)), translateCapVal(day.caps[n], day.temps[n])];
				if(tods){
					if (prepend)
						rawCapSeries.unshift(dataPoint);
					else
						rawCapSeries.push(dataPoint);

					capChartSeries.addPoint(dataPoint, false);
				} else {
					capSeries.push(dataPoint);

					if (day.caps_min != null) {
						dataPoint = [dataPoint[0], translateCapVal(day.caps_min[n], day.temps[n]), translateCapVal(day.caps_max[n], day.temps[n])];
						capMinMaxSeries.push(dataPoint);

						capMax = Math.max(capMax, dataPoint[2]); capMin = Math.min(capMin, dataPoint[1]);
					} else {
						capMax = Math.max(capMax, dataPoint[1]); capMin = Math.min(capMin, dataPoint[1]);
					}
				}
			}
			if (day.lux != null && day.lux[n]>0) {
				if (luxChartSeries == null) createLuxAxis();
				var dataPoint = [baseDate + (tods ? tods[n] * 1000 : HOUR * (n + 0.5)), day.lux[n]];
				if (tods) {
					if (prepend)
						rawLuxSeries.unshift(dataPoint);
					else
						rawLuxSeries.push(dataPoint);
					luxChartSeries.addPoint(dataPoint, false);
				} else {
					luxSeries.push(dataPoint);
					if (day.lux_min != null) {
						dataPoint = [dataPoint[0], day.lux_min[n], day.lux_max[n]];
						luxMinMaxSeries.push(dataPoint);
						luxMax = Math.max(luxMax, dataPoint[2]); luxMin = Math.min(luxMin, dataPoint[1]);
					} else {
						luxMax = Math.max(luxMax, dataPoint[1]); luxMin = Math.min(luxMin, dataPoint[1]);
					}
				}
			}

			if(day.temps[n]!=0.0){
				var val = translateTempVal( day.temps[n]);
				var dataPoint = [baseDate + (tods ? tods[n] * 1000 : HOUR * (n+0.5)), val];
				if (dataPoint[0] > dataRange.max) dataRange.max = dataPoint[0];

				avg+=val;
					
				if(tods){
					if (prepend)
						rawTempSeries.unshift(dataPoint);
					else
						rawTempSeries.push(dataPoint);

					chart.series[0].addPoint(dataPoint, false);
				} else {
					tempSeries.push(dataPoint);

					if (day.temps_min != null) {

						dataPoint = [dataPoint[0], translateTempVal(day.temps_min[n]), translateTempVal(day.temps_max[n])];
						tempMinMaxSeries.push(dataPoint);

						tempMax = Math.max(tempMax, dataPoint[2]); tempMin = Math.min(tempMin, dataPoint[1]);

					} else {
						tempMax = Math.max(tempMax, val); tempMin = Math.min(tempMin, val);
					}
				}
			}
		}
		avg/=count;
		
		if(!tods){
			//int bandi= findBandArrayIndexFor(baseDate,bandTempSeries);
			if(capSeries.length>0){
				bandCapSeries.push([baseDate+HOUR*12, capMin, capMax]);
			}
			if (luxSeries.length > 0)
				bandLuxSeries.push([baseDate + HOUR * 12, luxMin, luxMax]);

			bandTempSeries.push( [baseDate+HOUR*12, tempMin, tempMax]);
		}
		return avg;
	}
	var tempColor = "#CC2200", tempRangeColor="#FF8866";
	var capColor = "#007F00", capRangeColor = "#66E566";
	var luxColor = "#60A0DF", luxRangeColor = "#bfd9f2";

	function dataLoader(fromDate, toDate, onData){
		$.ajax({
			url: WSROOT + (isUUID ? "ethLogShared.asmx/GetStats"+(hasALS?"Lux":"")+"RawByUUID" : "ethLogs.asmx/GetStats"+(hasALS?"Lux":"")+"Raw"),
			data: JSON.stringify(isUUID? {uuid: slaveId, fromDate: fromDate, toDate: toDate} : { id: slaveId, fromDate: fromDate, toDate: toDate }),
			success: function (retval, textStatus) {
				onData(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				ajaxErrorHandler(xhr, exception);
			}
		});
	}
	function updateSeries(series, data, type) {
		if (series.type != type) series.update({ type: type },false);
		if(data!=null)series.setData(data, false);
	}
	function updateChartType(zoomLevel) {
		if (zoomLevel > ChartZoomLevelNormal) {
			updateSeries(chart.series[0], bandTempSeries, "arearange" );
			if (capChartSeries!=null)
				updateSeries(capChartSeries, bandCapSeries, "arearange");
			if (luxChartSeries != null)
				updateSeries(luxChartSeries, bandLuxSeries, "arearange");

			if (hourly_minmax) {
				tempMinMaxChartSeries.hide();
				if (capMinMaxChartSeries != null) capMinMaxChartSeries.hide();
				if (luxMinMaxChartSeries != null) luxMinMaxChartSeries.hide();
			}
			chart.redraw();
		}
		else if (zoomLevel == ChartZoomLevelNormal) {
			if (hourly_minmax) {

				updateSeries(chart.series[0], tempSeries, "line");
				if (capChartSeries != null)
					updateSeries(capChartSeries, capSeries, "line");
				if (luxChartSeries != null)
					updateSeries(luxChartSeries, luxSeries, "line");

				updateSeries(tempMinMaxChartSeries, tempMinMaxSeries, "arearange");				
				tempMinMaxChartSeries.show();

				if (capMinMaxChartSeries != null) {
					updateSeries(capMinMaxChartSeries, capMinMaxSeries, "arearange");
					capMinMaxChartSeries.show();
				}
				if (luxMinMaxChartSeries != null) {
					updateSeries(luxMinMaxChartSeries, luxMinMaxSeries, "arearange");
					luxMinMaxChartSeries.show();
				}
			} else {
				updateSeries(chart.series[0], tempSeries, "line" );
				if (capChartSeries!=null)
					updateSeries(capChartSeries, capSeries, "line");
				if (luxChartSeries != null)
					updateSeries(luxChartSeries, luxSeries, "line");
			}
			chart.redraw();
		}
		else
		{
			updateSeries(chart.series[0], null, "line" );
			if (capChartSeries!=null)
				updateSeries(capChartSeries, null, "line");
			if (luxChartSeries != null)
				updateSeries(luxChartSeries, null, "line");

			if (hourly_minmax) {
				tempMinMaxChartSeries.hide();
				if (capMinMaxChartSeries != null) capMinMaxChartSeries.hide();
				if (luxMinMaxChartSeries != null) luxMinMaxChartSeries.hide();
			}
			chart.redraw();
		}
	}
	function clearHourlyData() {
		tempSeries = []; tempMinMaxSeries = [];
		capSeries = []; capMinMaxSeries = [];
		luxSeries = []; luxMinMaxSeries = [];
		bandCapSeries = [];
		bandTempSeries = [];
		bandLuxSeries = [];
	}
	function clearCachedRawData() {
		rawTempSeries.length = 0;
		rawCapSeries.length = 0;
		rawLuxSeries.length = 0;
		chart.series[0].setData([]);
		if (capChartSeries!=null)
			capChartSeries.setData([]);
		if (luxChartSeries != null)
			luxChartSeries.setData([]);
	}
	function loadCachedRawData() {
		chart.series[0].setData(rawTempSeries);
		if (capChartSeries != null)
			capChartSeries.setData(rawCapSeries);
		if (luxChartSeries != null)
			luxChartSeries.setData(rawLuxSeries);
	}

	var options = {
		title: { text: tagName + " Temperature" + (capSeries.length > 0 ? (dewPointMode?"/Dew Point":"/Humidity") : "") + " Charts" },
		subtitle: {
			text: "Drag to zoom, hold Shift key and drag to pan"
		},
		animation: false,
		chart: {
			zoomType: 'x', panning: true, panKey: 'shift',
			style: { fontFamily: "ProximaNovaLight" },
			type: "line",
			events: {
				selection: function (event) {
					updateZoom(this, event.xAxis ? event.xAxis[0] : dataRange, function () { });
				}
			}
		},
		xAxis: {
			type: 'datetime',
			events: {
				setExtremes: function (event) {
					if (event.trigger == "pan") updatePan(this.chart, event);
					try {
						$("#custom_min").val(new Date(event.min - tzoffset).toISOString().substring(0, 10));
						$("#custom_max").val(new Date(event.max - tzoffset).toISOString().substring(0, 10));
					} catch (e) { }
				}
			},
			dateTimeLabelFormats: {
				hour: '%I:%M %p'
			}
		},
		yAxis: [{
		    title: { text: 'Temperature' }, allowDecimals: false
		}],
		tooltip: {
			borderColor: "gray",
			valueDecimals: 1,
			crosshairs: true,
			shared: true,
			followPointer: false,
			dateTimeLabelFormats: {
				second: "%A, %b %e, %I:%M:%S %p",
			}
		},
		legend: {
			layout: 'vertical', align: 'left', x: 80, verticalAlign: 'top', y: 40, floating: true,
			backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
		},
		series: [{
			name: 'Temperature',
			tooltip: {
				valueSuffix: " °" + (temp_unit == 1 ? "F" : "C")
			},
			color: tempColor
		}],
		exporting: {
			buttons: {
				dayButton: {
					text: 'Last 24 Hours',
					onclick: function () {
						var range = { min: dataRange.max - DAY, max: dataRange.max };
						updateZoom(holder.highcharts(), range, function () {
							holder.highcharts().xAxis[0].setExtremes(dataRange.max - DAY, dataRange.max);
						});
					}
				},
				weekButton: {
					text: 'Last Week',
					onclick: function () {
						var range = { min: dataRange.max - DAY * 7, max: dataRange.max };
						updateZoom(holder.highcharts(), range, function () {
							holder.highcharts().xAxis[0].setExtremes(dataRange.max - DAY * 7, dataRange.max);
						});
					}
				},
				monthButton: {
					text: 'Last 30 Days',
					onclick: function () {
						var range = { min: dataRange.max - DAY * 30, max: dataRange.max };
						updateZoom(holder.highcharts(), range, function () {
							holder.highcharts().xAxis[0].setExtremes(dataRange.max - DAY * 30, dataRange.max);
						});
					}
				},
				allButton: {
					text: 'All',
					onclick: function () {
						updateZoom(holder.highcharts(), dataRange, function () {
							holder.highcharts().xAxis[0].setExtremes(dataRange.min, dataRange.max);
						});
					}
				}
			}
		}
	};
	if (hasALS){
		options.exporting.buttons["luxAxisButton"] = {
			text: "Log/Linear Scale",
			onclick: function () {
				if (chart.yAxis[1].options.type == "linear")
					chart.yAxis[1].update({ type: "logarithmic" });
				else
					chart.yAxis[1].update({ type: "linear" });
			}
		};
	}
	
	holder.highcharts(options);

	var menuItems = Highcharts.getOptions().exporting.buttons.contextButton.menuItems;
	menuItems.unshift({ separator: true });
	for (button in options.exporting.buttons)
		menuItems.unshift(options.exporting.buttons[button]);

	resizeChart();
	chart = holder.highcharts();
	if (hourly_minmax) {
		tempMinMaxChartSeries = chart.addSeries({
			name: 'Temperature Highs/Lows', turboThreshold: 1e6,
			tooltip: {
				valueSuffix: " °" + (temp_unit == 1 ? "F" : "C")
			}, visible: false, color: tempRangeColor
		});
	}

	$("#zoomBtn").click(function () {
		var range = { min: new Date($("#custom_min").val()).getTime() + tzoffset, max: new Date($("#custom_max").val()).getTime() + 3600 * 1000 * 23.9 + tzoffset };
		updateZoom(holder.highcharts(), range, function () {
			holder.highcharts().xAxis[0].setExtremes(range.min, range.max);
		});
	});

	function updateTempUnit(d) {
		if (temp_unit == -1)
			temp_unit  = d.temp_unit;

		chart.yAxis[0].update({ labels: { format: '{value}°' + (temp_unit == 1 ? "F" : "C") } });
		chart.series[0].update({ tooltip: { valueSuffix: " °" + (temp_unit == 1 ? "F" : "C") } });
		if (dewPointMode && capChartSeries!=null)
			capChartSeries.update({ tooltip: { valueSuffix: " °" + (temp_unit == 1 ? "F" : "C") } });
	}
	var hourlyDataCache = {};
	function hourlyDataLoader(onData) {
		if (hourlyDataCache[since_calibration] != null)
		{
			onData(hourlyDataCache[since_calibration]);
			return;
		}

		$.ajax({
			url: WSROOT + (isUUID ? "ethLogShared.asmx/GetTemperature" + (hasALS ? "Lux" : "") + "StatsByUUID3" : "ethLogs.asmx/GetTemperature" + (hasALS ? "Lux" : "") + "Stats3"),
			data: JSON.stringify({ "id": slaveId , "withMinMax": hourly_minmax, "sinceLastCalibration": since_calibration}),
			success: function (retval, textStatus) {
				updateTempUnit(retval.d);
				hourlyDataCache[since_calibration] = retval.d.temps;
				onData(retval.d.temps);				
			},
			error: function (xhr, textStatus, exception) {
				ajaxErrorHandler(xhr, exception);
			}
		});
	}

	function dataSpanLoader(onData) {
		$.ajax({
			url: WSROOT + (isUUID ? "ethLogShared.asmx/GetMultiTagStatsSpanByUUIDs2" : "ethLogs.asmx/GetMultiTagStatsSpan2"),
			data: JSON.stringify({ "ids": [slaveId], "type": "temperature", "sinceLastCalibration": since_calibration }),
			success: function (retval, textStatus) {
				updateTempUnit(retval.d);
				onData(fileTimeToDate(retval.d.from).getTime(), fileTimeToDate(retval.d.to).getTime());
			},
			error: function (xhr, textStatus, exception) {
				ajaxErrorHandler(xhr, exception);
			}
		});
	}

	if (params.length > 1) {
		$.ajax({
			url: WSROOT + "ethAccount.asmx/ReflectAspxAuthCookie",
			data: JSON.stringify({ "cookie": params[1] }),
			success: function (retval, textStatus) {
				loadFirstData();
			}
		});
	}
	else
	{
		loadFirstData();
	}

	$('#deleteTemperatureLogBtn').click(function (e) {
		var btn = $('#deleteTemperatureLogBtn');
		$(e.target).simpledialog({ mode: 'bool', prompt: "This operation will permanently delete all temperature log data of this tag. Do you want to continue?",
			useModal: true, forceInput: true, cleanOnClose: true,
			'buttons': {
				'Yes': {
					click: function () {
						var oldhtml = show_finding(btn, "Deleting...")
						$.ajax({ url: WSROOT + "ethLogs.asmx/DeleteTemperatureData",
							data: "{id: " + slaveId + "}",
							complete: function () { restore_finding(btn, oldhtml); },
							success: function (retval) {
								holder.empty();
								holder.html("<center>"+retval.d + " records permanently removed.</center>");
							}
						});
					}, icon: "forward"
				},
				'Cancel': { click: function () {
				}, icon: "back"
				}
			}
		});
	});


	</script> 
	</div>

</body>
</html>