Start of the merge with another unfinished project

Sat, 11 Aug 2018 22:49:44 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 11 Aug 2018 22:49:44 +0200
changeset 10
606b4af8f918
parent 9
5b384299cc53
child 11
d341f0a91a91

Start of the merge with another unfinished project

www/Makefile file | annotate | diff | comparison | revisions
www/images/add.png file | annotate | diff | comparison | revisions
www/images/help.png file | annotate | diff | comparison | revisions
www/images/search.png file | annotate | diff | comparison | revisions
www/includes/db_inventory_suppliers.php file | annotate | diff | comparison | revisions
www/includes/global.inc.php file | annotate | diff | comparison | revisions
www/index.php file | annotate | diff | comparison | revisions
www/js/inv_suppliers.js file | annotate | diff | comparison | revisions
www/monitor.php file | annotate | diff | comparison | revisions
--- a/www/Makefile	Sat Aug 11 19:16:51 2018 +0200
+++ b/www/Makefile	Sat Aug 11 22:49:44 2018 +0200
@@ -3,10 +3,12 @@
 
 include ../Makefile.global
 
-SRC		= index.php getfermenter.php  getfermenters.php  \
-		  getnode.php  getnodes.php config.php.dist 
+SRC		= monitor.php getfermenter.php  getfermenters.php  \
+		  getnode.php  getnodes.php config.php.dist \
+		  inv_suppliers.php
 SUB		= version.php.in images/* css/* jqwidgets/* jqwidgets/styles/* \
-		  jqwidgets/styles/images/* jqwidgets/globalization/* js/*
+		  jqwidgets/styles/images/* jqwidgets/globalization/* js/* \
+		  includes/*
 OTHER		= Makefile
 
 #############################################################################
Binary file www/images/add.png has changed
Binary file www/images/help.png has changed
Binary file www/images/search.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/includes/db_inventory_suppliers.php	Sat Aug 11 22:49:44 2018 +0200
@@ -0,0 +1,76 @@
+<?php
+
+require($_SERVER['DOCUMENT_ROOT']."/config.php");
+require($_SERVER['DOCUMENT_ROOT']."/version.php");
+
+#Connect to the database
+$connect = mysqli_connect(DBASE_HOST, DBASE_USER, DBASE_PASS, DBASE_NAME);
+if (! $connect) {
+	die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
+}
+
+// get data and store in a json array
+$query = "SELECT * FROM inventory_suppliers";
+if (isset($_GET['insert'])) {
+	// INSERT COMMAND
+	$sql  = "INSERT INTO `inventory_suppliers` SET name='" . mysqli_real_escape_string($connect, $_GET['name']);
+	$sql .= "', address='" . mysqli_real_escape_string($connect, $_GET['address']);
+	$sql .= "', city='" . mysqli_real_escape_string($connect, $_GET['city']);
+	$sql .= "', zip='" . mysqli_real_escape_string($connect, $_GET['zip']);
+	$sql .= "', country='" . mysqli_real_escape_string($connect, $_GET['country']);
+	$sql .= "', website='" . mysqli_real_escape_string($connect, $_GET['website']);
+	$sql .= "', email='" . mysqli_real_escape_string($connect, $_GET['email']);
+	$sql .= "', phone='" . mysqli_real_escape_string($connect, $_GET['phone']);
+	$sql .= "', notes='" . mysqli_real_escape_string($connect, $_GET['notes']);
+	$sql .= "';";
+	error_log("\"$sql\"");
+	$result = mysqli_query($connect, $sql) or die("SQL Error 1: " . mysqli_error($connect));
+	error_log("result " . $result);
+	echo $result;
+
+} else if (isset($_GET['update'])) {
+	// UPDATE COMMAND
+	$sql  = "UPDATE `inventory_suppliers` SET name='" . mysqli_real_escape_string($connect, $_GET['name']);
+	$sql .= "', address='" . mysqli_real_escape_string($connect, $_GET['address']);
+	$sql .= "', city='" . mysqli_real_escape_string($connect, $_GET['city']);
+	$sql .= "', zip='" . mysqli_real_escape_string($connect, $_GET['zip']);
+	$sql .= "', country='" . mysqli_real_escape_string($connect, $_GET['country']);
+	$sql .= "', website='" . mysqli_real_escape_string($connect, $_GET['website']);
+	$sql .= "', email='" . mysqli_real_escape_string($connect, $_GET['email']);
+	$sql .= "', phone='" . mysqli_real_escape_string($connect, $_GET['phone']);
+	$sql .= "', notes='" . mysqli_real_escape_string($connect, $_GET['notes']);
+	$sql .= "' WHERE record='" . $_GET['record'] . "';";
+	error_log("\"$sql\"");
+	$result = mysqli_query($connect, $sql) or die("SQL Error 1: " . mysqli_error($connect));
+	error_log("result " . $result);
+	echo $result;
+
+} else if (isset($_GET['delete'])) {
+	// DELETE COMMAND
+	// FIXME: need to check if the record is in use
+	$sql = "DELETE FROM `inventory_suppliers` WHERE record='".$_GET['record']."';";
+	error_log("\"$sql\"");
+	$result = mysqli_query($connect, $sql) or die("SQL Error 1: " . mysqli_error($connect));
+	error_log("result " . $result);
+	echo $result;
+
+} else {
+	// SELECT COMMAND
+	$result = mysqli_query($connect, $query) or die("SQL Error 1: " . mysqli_error($connect));
+	while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
+		$suppliers[] = array(
+			'record' => $row['record'],
+			'name' => $row['name'],
+			'address' => $row['address'],
+			'city' => $row['city'],
+			'zip' => $row['zip'],
+			'country' => $row['country'],
+			'website' => $row['website'],
+			'email' => $row['email'],
+			'phone' => $row['phone'],
+			'notes' => $row['notes']
+		);
+	}
+	echo json_encode($suppliers);
+}
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/includes/global.inc.php	Sat Aug 11 22:49:44 2018 +0200
@@ -0,0 +1,136 @@
+<?php
+/*****************************************************************************
+ * Copyright (C) 2014-2018
+ *   
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of Brewery Management System
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * BrewCloud is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with ThermFerm; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *****************************************************************************/
+
+/*
+ * Look for the style names in the jqwidgets/styles directory.
+ *
+ * energyblue of ui-redmond
+ */
+#$my_style = 'mbse-dark';
+$my_style = 'ui-redmond';
+$my_style = 'android';
+
+require_once($_SERVER['DOCUMENT_ROOT'].'/config.php');
+require_once($_SERVER['DOCUMENT_ROOT'].'/version.php');
+
+
+function page_header($title, $loadjs) {
+	global $my_style;
+
+	$outstr  = '<!DOCTYPE html>'.PHP_EOL;
+	$outstr .= '<html lang=nl-NL>'.PHP_EOL;
+	$outstr .= ' <head>'.PHP_EOL;
+	$outstr .= '  <meta http-equiv="content-type" content="text/html; charset=utf-8" />'.PHP_EOL;
+	$outstr .= '  <title>BMS v'.$my_version.' - ' . $title . '</title>'.PHP_EOL;
+	$outstr .= '  <link type="text/css" href="css/style.css" rel="stylesheet" media="all" />'.PHP_EOL;
+	$outstr .= '  <link type="text/css" href="jqwidgets/styles/jqx.base.css" rel="stylesheet" />'.PHP_EOL;
+	$outstr .= '  <link type="text/css" href="jqwidgets/styles/jqx.'.$my_style.'.css" rel="stylesheet" />'.PHP_EOL;
+	$outstr .= '  <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" />'.PHP_EOL;
+	$outstr .= '  <script>'.PHP_EOL;
+	$outstr .= '   var theme = "'.$my_style.'";'.PHP_EOL;
+	$outstr .= '  </script>'.PHP_EOL;
+	$outstr .= '  <script src="js/jquery-1.11.1.min.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxcore.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxwindow.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxmenu.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxwindow.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxdata.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxbuttons.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxscrollbar.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxgrid.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxgrid.pager.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxgrid.filter.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxgrid.selection.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxnumberinput.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxlistbox.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxdropdownlist.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxdropdownbutton.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxinput.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxeditor.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxtooltip.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxcheckbox.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxdatetimeinput.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/jqxcalendar.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="jqwidgets/globalization/globalize.js"></script>'.PHP_EOL;
+	$outstr .= '  <script src="js/global.js"></script>'.PHP_EOL;
+	if (strlen($loadjs))
+		$outstr .= '  <script src="js/'.$loadjs.'.js"></script>'.PHP_EOL;
+	$outstr .= ' </head>'.PHP_EOL;
+	$outstr .= ' <body class="default">'.PHP_EOL;
+	$outstr .= '  <div id="jqxWidget">'.PHP_EOL;
+
+	/*
+	 * Menu
+	 */
+	$outstr .= '   <div id="jqxMenu">'.PHP_EOL;
+	$outstr .= '    <ul>'.PHP_EOL;
+	$outstr .= '     <li><a href="#Home">Home</a></li>'.PHP_EOL;
+	$outstr .= '     <li>Monitoren'.PHP_EOL;
+	$outstr .= '      <ul>'.PHP_EOL;
+	$outstr .= '       <li><a href="monitor.php">Probeersel</a></li>'.PHP_EOL;
+	$outstr .= '      </ul>'.PHP_EOL;
+	$outstr .= '     </li>'.PHP_EOL; // Monitoren
+	$outstr .= '     <li>Inventaris'.PHP_EOL;
+	$outstr .= '      <ul>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_suppliers.php">Leveranciers</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_fermentables.php">Vergistbare producten</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_hops.php">Hoppen</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_yeasts.php">Gist</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_waters.php">Water profielen</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_miscs.php">Diverse ingredienetn</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_mashs.php">Maisch profielen</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_equipments.php">Brouw apparatuur</a></li>'.PHP_EOL;
+	$outstr .= '       <li><a href="inv_styles.php">Bier stijlen</a></li>'.PHP_EOL;
+	$outstr .= '      </ul>'.PHP_EOL;
+	$outstr .= '     </li>'.PHP_EOL; // Inventaris
+	$outstr .= '     <li>About'.PHP_EOL;
+	$outstr .= '      <ul>'.PHP_EOL;
+	$outstr .= '       <li><a href="#aboutWindow">Informatie</a></li>'.PHP_EOL;
+	$outstr .= '      </ul>'.PHP_EOL;
+	$outstr .= '     </li>'.PHP_EOL;
+	$outstr .= '    </ul>'.PHP_EOL;
+	$outstr .= '   </div>'.PHP_EOL;
+
+	$outstr .= '   <div id="aboutWindow">'.PHP_EOL;
+	$outstr .= '    <div>'.PHP_EOL;
+	$outstr .= '     About BrewCloud'.PHP_EOL;
+	$outstr .= '    </div>'.PHP_EOL;
+	$outstr .= '    <div>'.PHP_EOL;
+	$outstr .= '     The about text comes here'.PHP_EOL;
+	$outstr .= '    </div>'.PHP_EOL;
+	$outstr .= '   </div>'.PHP_EOL;
+
+	return $outstr;
+}
+
+
+function page_footer() {
+
+	$outstr  = '  </div> <!-- jqxWidget -->'.PHP_EOL;
+	$outstr .= ' </body>'.PHP_EOL;
+	$outstr .= '</html>'.PHP_EOL;
+
+	return $outstr;
+}
+
+
--- a/www/index.php	Sat Aug 11 19:16:51 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-<?php
-$my_style = 'android';
-require_once('version.php');
-?>
-<!DOCTYPE html>
-<html lang="en">
- <head>'
-  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-  <title id='Description'>Brewery Managment System v<?php echo $my_version; ?></title>
-  <link type="text/css" href="css/style.css" rel="stylesheet" media="all" />
-  <link type="text/css" href="jqwidgets/styles/jqx.base.css" rel="stylesheet" />
-  <link type="text/css" href="jqwidgets/styles/jqx.<?php echo $my_style; ?>.css" rel="stylesheet" />
-  <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" />
-  <script src="js/jquery-1.11.1.min.js"></script>
-  <script src="jqwidgets/jqxcore.js"></script>
-  <script src="jqwidgets/jqxbuttons.js"></script>
-  <script src="jqwidgets/jqxscrollbar.js"></script>
-  <script src="jqwidgets/jqxpanel.js"></script>
-  <script src="jqwidgets/jqxtree.js"></script>
-  <script src="jqwidgets/jqxexpander.js"></script>
-  <script src="jqwidgets/jqxsplitter.js"></script>
-  <script src="jqwidgets/jqxdata.js"></script>
-  <script src="jqwidgets/jqxcheckbox.js"></script>
-  <script src="jqwidgets/jqxradiobutton.js"></script>
-  <script src="jqwidgets/jqxchart.core.js"></script>
-  <script src="jqwidgets/jqxgauge.js"></script>
-  <script src="jqwidgets/jqxdraw.js"></script>
-  <script src="jqwidgets/jqxtooltip.js"></script>
-  <script>
-  $(document).ready(function () {
-    /*
-     * Different right panel pages
-     */
-    var refreshIntervalId = 0;
-    $("#fermenter_thermometers").hide();
-    $("#splitter").jqxSplitter({ theme: "<?php echo $my_style; ?>", width: 1278, height: 618, panels: [{ size: 250}] });
-    $("#jqxTree").jqxTree({ theme: "<?php echo $my_style; ?>", height: "100%", width: "100%" });
-    /*
-     * Build the nodes subtree
-     */
-    var nodeByID = $("#jqxTree").find("#Nodes")[0];
-    $.getJSON("getnodes.php", function(data) {
-      for( i = 0; i < data.length; i++ ) {
-	 $("#jqxTree").jqxTree("addTo", { id: 'node-' + data[i].uuid, label: data[i].node, icon: 'images/folder.png'  }, nodeByID);
-      }
-    });
-    /*
-     * Build the fermenters subtree
-     */
-    var fermenterByID = $("#jqxTree").find("#Fermenters")[0];
-    $.getJSON("getfermenters.php", function(data) {
-      for( i = 0; i < data.length; i++ ) {
-        $("#jqxTree").jqxTree("addTo", { id: 'fermenter-' + data[i].uuid, label: data[i].node + "/" + data[i].alias, icon: 'images/folder.png' }, fermenterByID);
-      }
-    });
-
-    $("#jqxTree").css("visibility", "visible");
-
-    $("#jqxTree").on("select", function (event) {
-      /*
-       * Cancel a running refresh loop.
-       */
-      if (refreshIntervalId > 0) {
-	console.log( "RefreshIIntervald: " + refreshIntervalId + " stopped" );
-        clearInterval(refreshIntervalId);
-	refreshIntervalId = 0;
-      }
-      $("#fermenter_thermometers").hide();
-      $("#gaugeContainer_air").hide();
-      $("#gaugeContainer_beer").hide();
-      $("#gaugeContainer_chiller").hide();
-      /*
-       * Process the selected id from the left panel tree and show the correct page in the right panel.
-       */
-      var estr = event.args.element.id;
-      if (estr == "Root") {
-	$("#ContentPanel").html("<div style='margin: 10px;'>RrrR</div>");
-
-      } else if (estr.indexOf("node-", 0) == 0) {
-	// Load and show a node.
-	// The parameter is: node-36d4d030-4d62-4f2f-a96b-472e643687f7
-        var uuid = estr.substr(5);
-	var url = "getnode.php?uuid='" + uuid + "'";
-        var source = {
-          datatype: "json",
-          datafields: [
-            { name: 'record', type: 'int' },
-            { name: 'uuid', type: 'string' },
-            { name: 'node', type: 'string' },
-            { name: 'online', type: 'bool' },
-            { name: 'group_id', type: 'string' },
-            { name: 'hardwaremake', type: 'string' },
-            { name: 'hardwaremodel', type: 'string' },
-            { name: 'os', type: 'string' },
-            { name: 'os_version', type: 'string' },
-            { name: 'firmware', type: 'string' },
-            { name: 'firstseen', type: 'string' },
-            { name: 'lastseen', type: 'string' },
-            { name: 'temperature', type: 'float' },
-            { name: 'humidity', type: 'float' },
-            { name: 'barometer', type: 'float' },
-            { name: 'gps_latitude', type: 'float' },
-            { name: 'gps_longitude', type: 'float' },
-            { name: 'gps_altitude', type: 'float' },
-            { name: 'net_address', type: 'string' },
-            { name: 'net_ifname', type: 'string' },
-            { name: 'net_rssi', type: 'int' }
-          ],
-          id: 'record',
-          url: url
-        };
-	var dataAdapter = new $.jqx.dataAdapter(source, {
-	  loadComplete: function (records) {
-	    var record = dataAdapter.records[0];
-	    var html  = "<div style='background: #252526; margin: 50px;'>";
-	        html += "<table style='width: 100%; padding: 10px;'>";
-	        html += "<tr><th colspan=2>Systeem overzicht</th></tr>";
-                html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>";
-                html += "<tr><td>Systeem</td><td>" + record.node + "</td></tr>";
-	        html += "<tr><td>Online</td><td>" + record.online + "</td></tr>";
-		html += "<tr><td>Type</td><td>" + record.group_id + "</td></tr>";
-		html += "<tr><td>Eerst gezien</td><td>" + record.firstseen + "</td></tr>";
-		html += "<tr><td>Laatst gezien</td><td>" + record.lastseen + "</td></tr>";
-	        html += "<tr><td>Hardware maker</td><td>" + record.hardwaremake+ "</td></tr>";
-		html += "<tr><td>Hardware model</td><td>" + record.harwaremodel+ "</td></tr>";
-		html += "<tr><td>OS</td><td>" + record.os + " versie: " + record.os_version + "</td></tr>";
-		html += "<tr><td>Firmware</td><td>" + record.firmware + "</td></tr>";
-		if (record.online) {
-		  html += "<tr><td>Temperatuur</td><td>" + record.temperature + "&deg;C</td></tr>";
-		  if (record.humidity > 0) {
-		    html += "<tr><td>Vochtigheid</td><td>" + record.humidity + "%</td></tr>";
-		  }
-	          if (record.barometer > 0) {
-		    html += "<tr><td>Luchtdruk</td><td>" + record.barometer + "</td></tr>";
-		  }
-		  if ((record.gps_latitude != 0) && (record.gps_longitude != 0)) {
-		    html += "<tr><td>GPS</td><td>"+ record.gps_latitude + " " + record.gps_longitude + " " + record.gps_altitude + "</td></tr>";
-		  }
-		  html += "<tr><td>Netwerk</td><td>"+ record.net_ifname + " " + record.net_address + "</td></tr>";
-		}
-		html += "</<table>";
-	        html += "</div>";
-	    $("#ContentPanel").html(html);
-	  }
-	});
-	// Get the data immediatly and then at regular intervals to refresh.
-	dataAdapter.dataBind();
-	refreshIntervalId = setInterval(function(){
-          dataAdapter.dataBind();
-	}, 30000);
-
-      } else if (estr.indexOf("fermenter-", 0) == 0) {
-	// Load and show a fermenter.
-	// The parameter is: fermenter-36d4d030-4d62-4f2f-a96b-472e643687f7
-        var gaugeoptions = {
-	  min: -5, max: 35, width: 275, height: 275,
-	  ranges: [{ startValue: -5, endValue:  0, style: { fill: '#3399FF', stroke: '#3399FF' }, endWidth: 10, startWidth: 10 },
-	           { startValue:  0, endValue: 16, style: { fill: '#00CC33', stroke: '#00CC33' }, endWidth: 10, startWidth: 10 },
-	           { startValue: 16, endValue: 24, style: { fill: '#FCA76A', stroke: '#FCA76A' }, endWidth: 10, startWidth: 10 },
-	           { startValue: 24, endValue: 35, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }, endWidth: 10, startWidth: 10 }],
-	  ticksMinor: { interval: 1, size: '5%' },
-	  ticksMajor: { interval: 5, size: '9%' },
-	  labels: { interval: 5 },
-	  style: { fill: '#eeeeee', stroke: '#666666' },
-	  value: 0,
-	  colorScheme: 'scheme05',
-	  animationDuration: 1200
-        };
-	var gaugeSmalloptions = {
-	  min: -20, max: 25, width: 150, height: 150,
-	  ranges: [{ startValue: -20, endValue:  0, startWidth: 5, endWidth: 5, style: { fill: '#3399FF', stroke: '#3399FF' }},
-	           { startValue:   0, endValue: 25, startWidth: 5, endWidth: 5, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }}],
-	  ticksMinor: { interval: 1, size: '5%' },
-	  ticksMajor: { interval: 5, size: '9%' },
-	  labels: { interval: 5 },
-	  style: { fill: '#eeeeee', stroke: '#666666' },
-	  value: 0,
-	  colorScheme: 'scheme05',
-	  animationDuration: 1200,
-	  caption: { value: 'Chiller', position: 'bottom', offset: [0, 10] }
-	};
-	$("#fermenter_thermometers").show();
-	$("#gaugeContainer_air").show();
-	$("#gaugeContainer_air").jqxGauge( gaugeoptions );
-	$("#gaugeContainer_air").jqxGauge( { caption: { value: 'Air', position: 'bottom', offset: [0, 10] }} );
-	$("#gaugeContainer_beer").show();
-	$("#gaugeContainer_beer").jqxGauge( gaugeoptions );
-	$("#gaugeContainer_beer").jqxGauge( { caption: { value: 'Beer', position: 'bottom', offset: [0, 10] }} );
-	$("#gaugeContainer_chiller").show();
-	$("#gaugeContainer_chiller").jqxGauge( gaugeSmalloptions );
-	var uuid = estr.substr(10);
-	var url = "getfermenter.php?uuid='" + uuid + "'";
-	var source = {
-	  datatype: "json",
-	  datafields: [
-	    { name: 'record', type: 'int' },
-	    { name: 'uuid', type: 'string' },
-	    { name: 'alias', type: 'string' },
-	    { name: 'node', type: 'string' },
-	    { name: 'online', type: 'bool' },
-	    { name: 'beercode', type: 'string' },
-	    { name: 'beername', type: 'string' },
-	    { name: 'air_address', type: 'string' },
-	    { name: 'air_state', type: 'string' },
-	    { name: 'air_temperature', type: 'float' },
-	    { name: 'beer_address', type: 'string' },
-	    { name: 'beer_state', type: 'string' },
- 	    { name: 'beer_temperature', type: 'float' },
-	    { name: 'chiller_address', type: 'string' },
-	    { name: 'chiller_state', type: 'string' },
-	    { name: 'chiller_temperature', type: 'float' },
-	    { name: 'heater_address', type: 'string' },
-	    { name: 'heater_state', type: 'int' },
-	    { name: 'heater_usage', type: 'int' },
-	    { name: 'cooler_address', type: 'string' },
-	    { name: 'cooler_state', type: 'int' },
-	    { name: 'cooler_usage', type: 'int' },
-	    { name: 'fan_address', type: 'string' },
-	    { name: 'fan_state', type: 'int' },
-	    { name: 'fan_usage', type: 'int' },
-	    { name: 'light_address', type: 'string' },
-	    { name: 'light_state', type: 'int' },
-	    { name: 'light_usage', type: 'int' },
-	    { name: 'door_address', type: 'string' },
-	    { name: 'door_state', type: 'int' },
-	    { name: 'psu_address', type: 'string' },
-	    { name: 'psu_state', type: 'int' },
-	    { name: 'mode', type: 'string' },
-	    { name: 'alarm', type: 'int' },
-	    { name: 'setpoint_high', type: 'float' },
-	    { name: 'setpoint_low', type: 'float' },
-	    { name: 'profile_uuid', type: 'string' },
-	    { name: 'profile_name', type: 'string' },
-	    { name: 'profile_state', type: 'string' },
-	    { name: 'profile_precent', type: 'int' },
-	    { name: 'profile_inittemp_high', type: 'float' },
-	    { name: 'profile_inittemp_low', type: 'float' },
-	    { name: 'profile_steps', type: 'string' },
-	    { name: 'stage', type: 'string' }
-    	  ],
-    	  id: 'record',
-          url: url
-	};
-        var dataAdapter = new $.jqx.dataAdapter(source, {
-	  loadComplete: function (records) {
-		  var record = dataAdapter.records[0];
-	    var oline = (record.online) ? "On-line" : "Off-line";
-	    var html  = "<div id='fermenter_table'>";
-	    html += "<table style='width: 100%; padding: 10px;'>";
-	    html += "<tr><th colspan=2>Klimaatkast overzicht</th></tr>";
-	    html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>";
-	    html += "<tr><td>Systeem</td><td>" + record.node +  "/" + record.alias + " " + oline + "</td></tr>";
-	    html += "<tr><td>Bier</td><td>" + record.beercode + " - " + record.beername + "</td></tr>";
-	    html += "<tr><td>Werking</td><td>" + record.mode + "</td></tr>";
-	    html += "<tr><td>Fase</td><td>" + record.stage + "</td></tr>"
-	    html += "</<table>";
-	    html += "</div>";
-	    $("#ContentPanel").html(html);
-	    $('#gaugeContainer_air').jqxGauge({ value: record.air_temperature });
-	    if (record.online && (record.air_state == "OK")) {
-	      $("#gaugeContainer_air").jqxGauge({ disabled: false });
-	    } else {
-	      $("#gaugeContainer_air").jqxGauge({ disabled: true });
-	    }
-	    $('#gaugeContainer_beer').jqxGauge({ value: record.beer_temperature });
-	    if (record.online && (record.beer_state == "OK")) {
-	      $("#gaugeContainer_beer").jqxGauge({ disabled: false });
-	    } else {
-	      $("#gaugeContainer_beer").jqxGauge({ disabled: true });
-	    }
-	    $("#gaugeContainer_chiller").jqxGauge({ value: record.chiller_temperature });
-	    if (record.online && (record.chiller_state == "OK")) {
-	      $("#gaugeContainer_chiller").jqxGauge({ disabled: false });
-	    } else {
-	      $("#gaugeContainer_chiller").jqxGauge({ disabled: true });
-	    }
-	    html  = "<div>SpH <span class='temperature NUM'>" + record.setpoint_high + "</span></div>";
-	    html += "<div>SpL <span class='temperature NUM'>" + record.setpoint_low + "</span></div>";
-	    html += "<div>Air <span class='temperature NUM'>" + record.air_temperature + "</span></div>";
-	    html += "<div>Beer <span class='temperature NUM'>" + record.beer_temperature + "</span></div>";
-	    $("#fermenter_tempdigits").html(html);
-	  }
-	});
-	// Get the data immediatly and then at regular intervals to refresh.
-	dataAdapter.dataBind();
-	refreshIntervalId = setInterval(function(){
-	  dataAdapter.dataBind();
-	}, 10000);
-
-      } else if (event.args.element.id == "Nodes") {
-        $("#ContentPanel").html("<div></div");
-      } else {
-        $("#ContentPanel").html("<div style='margin: 10px;'>" + event.args.element.id + "</div>");
-      }
-    });
-  });
-  </script>
- </head>
-
- <body class="default">
-  <div id="jqxWidget">
-   <div id="header">
-   <div id="title">BMS <?php echo $my_version; ?></div>
-   </div> <!-- header -->
-   <div id="splitter">
-    <div> <!-- tree panel -->
-     <div style="visibility: hidden; border: none;" id='jqxTree'>
-      <ul>
-       <li id="Root" item-expanded='true'>
-        <img style='float: left; margin-right: 5px;' src='images/earth.png' />
-        <span item-title="true">Root</span>
-        <ul>
-         <li id="Nodes">
-          <img style='float: left; margin-right: 5px;' src='images/folder.png' />
-          <span item-title="true">Systemen</span>
-          <!-- Subtree nodes -->
-         </li>
-         <li id="Fermenters">
-          <img style='float: left; margin-right: 5px;' src='images/folder.png' />
-          <span item-title="true">Klimaatkasten</span>
-          <!-- Subtree fermenters -->
-         </li>
-         <li id="Brewboards">
-          <img src='images/settings.png' />
-          <span item-title="true">Brouw apparatuur</span>
-         </li>
-         <li id="Prducing">
-          <img src='images/system.png' />
-          <span item-title="true">In productie</span>
-         </li>
-         <li id="Recipes">
-          <img style='float: left; margin-right: 5px;' src='images/beer.png' />
-          <span item-title="true">Recepten</span>
-         </li>
-         <li id="Settings">
-          <img style='float: left; margin-right: 5px;' src='images/setupIcon.png' />
-          <span item-title="true">Instellingen</span>
-         </li>
-        </ul>
-       </li>
-      </ul>
-     </div> <!-- jqxTree -->
-    </div> <!-- tree panel -->
-    <div id="RightPanel">
-     <div id="ContentPanel"></div>
-     <div id='fermenter_thermometers'>
-      <div id="gaugeContainer_air" style='float: left; margin-top: 10px; margin-left: 10px;'></div>
-      <div id="gaugeContainer_beer" style="float: right; margin-top: 10px; margin-right: 10px;"></div>
-      <div id="gaugeContainer_chiller" style="float: left; margin-top: 15px;"></div>
-      <div id="fermenter_tempdigits"></div>
-     </div>
-    </div>
-   </div> <!--- splitter -->
-  </div> <!-- jqxWidget -->
- </body>
-</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/js/inv_suppliers.js	Sat Aug 11 22:49:44 2018 +0200
@@ -0,0 +1,243 @@
+/*****************************************************************************
+ * Copyright (C) 2014-2018
+ *   
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of Brewery Management System
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * BrewCloud is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with ThermFerm; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *****************************************************************************/
+
+
+function createDelElements() {
+	$('#eventWindow').jqxWindow({
+		theme: theme,
+		position: { x: 355, y: 210 },
+		width: 270,
+		resizable: false,
+		isModal: true,
+		modalOpacity: 0.4,
+		okButton: $('#delOk'),
+		cancelButton: $('#delCancel'),
+		initContent: function () {
+			$('#delOk').jqxButton({ width: '65px', theme: theme });
+			$('#delCancel').jqxButton({ width: '65px', theme: theme });
+			$('#delCancel').focus();
+		}
+	});
+	$('#eventWindow').jqxWindow('hide');
+}
+
+
+$(document).ready(function () {
+	var url = "includes/db_inventory_suppliers.php";
+	// prepare the data
+	var source = {
+		datatype: "json",
+		cache: false,
+		datafields: [
+			{ name: 'record', type: 'number' },
+			{ name: 'name', type: 'string' },
+			{ name: 'address', type: 'string' },
+			{ name: 'city', type: 'string' },
+			{ name: 'zip', type: 'string' },
+			{ name: 'country', type: 'string' },
+			{ name: 'website', type: 'string' },
+			{ name: 'email', type: 'string' },
+			{ name: 'phone', type: 'string' },
+			{ name: 'notes', type: 'string' }
+		],
+		id: 'record',
+		url: url,
+		deleterow: function (rowid, commit) {
+			// synchronize with the server - send delete command
+			var data = "delete=true&" + $.param({ record: rowid });
+			$.ajax({
+				dataType: 'json',
+				url: url,
+				cache: false,
+				data: data,
+				success: function (data, status, xhr) {
+					// delete command is executed.
+					commit(true);
+				},
+				error: function (jqXHR, textStatus, errorThrown) {
+					commit(false);
+				}
+			});
+		},
+		addrow: function (rowid, rowdata, position, commit) {
+			var data = "insert=true&" + $.param(rowdata);
+			$.ajax({
+				dataType: 'json',
+				url: url,
+				cache: false,
+				data: data,
+				success: function (data, status, xhr) {
+					commit(true);
+				},
+				error: function(jqXHR, textStatus, errorThrown) {
+                                        commit(false);
+                                }
+                        });
+                },
+		updaterow: function (rowid, rowdata, commit) {
+			var data = "update=true&" + $.param(rowdata);
+			$.ajax({
+				dataType: 'json',
+				url: url,
+				cache: false,
+				data: data,
+				success: function (data, status, xhr) {
+					// update command is executed.
+					commit(true);
+				},
+				error: function(jqXHR, textStatus, errorThrown) {
+					commit(false);
+				}
+			});
+		}
+	};
+	// initialize the input fields.
+	$("#name").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#address").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#zip").jqxInput({ theme: theme, width: 120, height: 23 });
+	$("#city").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#country").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#website").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#email").jqxInput({ theme: theme, width: 250, height: 23 });
+	$("#phone").jqxInput({ theme: theme, width: 120, height: 23 });
+	$("#notes").jqxInput({ theme: theme, width: 640, height: 48 });
+
+	var dataAdapter = new $.jqx.dataAdapter(source);
+	var editrow = -1;
+	// initialize jqxGrid
+	$("#jqxgrid").jqxGrid({
+		width: 980,
+		source: dataAdapter,
+		theme: theme,
+		showstatusbar: true,
+		renderstatusbar: function (statusbar) {
+			var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>");
+			var addButton = $("<div style='float: right; margin-right: 15px;'><img style='position: relative; margin-top: 2px;' src='images/add.png'/><span style='margin-left: 4px; position: relative; top: -3px;'>Add</span></div>");
+			container.append(addButton);
+			statusbar.append(container);
+			addButton.jqxButton({  width: 60, height: 20 });
+			// add new row.
+			addButton.click(function (event) {
+				editrow = -1;
+				$("#popupWindow").jqxWindow({ position: { x: 80, y: 10 } });
+				$("#name").val('');
+				$("#address").val('');
+				$("#city").val('');
+				$("#zip").val('');
+				$("#country").val('');
+				$("#website").val('');
+				$("#email").val('');
+				$("#phone").val('');
+				$("#notes").val('');
+				$("#popupWindow").jqxWindow('open');
+			});
+		},
+		filterable: true,
+		filtermode: 'excel',
+		columns: [
+			{ text: 'Supplier Name', datafield: 'name', width: 250 },
+			{ text: 'City', datafield: 'city', width: 250 },
+			{ text: 'Country', datafield: 'country', width: 250 },
+			{ text: 'Phone', datafield: 'phone', width: 100 },
+			{ text: 'Edit', datafield: 'Edit', columntype: 'button', cellsrenderer: function () {
+				return "Edit";
+				}, buttonclick: function (row) {
+					// open the popup window when the user clicks a button.
+					editrow = row;
+					$("#popupWindow").jqxWindow({ position: { x: 80, y: 10 } });
+					// get the clicked row's data and initialize the input fields.
+					var dataRecord = $("#jqxgrid").jqxGrid('getrowdata', editrow);
+					$("#name").val(dataRecord.name);
+					$("#address").val(dataRecord.address);
+					$("#city").val(dataRecord.city);
+					$("#zip").val(dataRecord.zip);
+					$("#country").val(dataRecord.country);
+					$("#website").val(dataRecord.website);
+					$("#email").val(dataRecord.email);
+					$("#phone").val(dataRecord.phone);
+					$("#notes").val(dataRecord.notes);
+					// show the popup window.
+					$("#popupWindow").jqxWindow('open');
+				}
+			}
+		]
+	});
+	// initialize the popup window and buttons.
+	$("#popupWindow").jqxWindow({
+		width: 860, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#Cancel"), modalOpacity: 0.40           
+	});
+	$("#popupWindow").on('open', function () {
+		$("#name").jqxInput('selectAll');
+	});
+	$("#Delete").jqxButton({ theme: theme });
+	$("#Delete").click(function () {
+		if (editrow >= 0) {
+			// Open a popup to confirm this action.
+			$('#eventWindow').jqxWindow('open');
+			$("#delOk").click(function () {
+				var rowID = $('#jqxgrid').jqxGrid('getrowid', editrow);
+				$("#jqxgrid").jqxGrid('deleterow', rowID);
+			});
+		}
+		$("#popupWindow").jqxWindow('hide');
+	});
+	$("#Cancel").jqxButton({ theme: theme });
+	$("#Save").jqxButton({ theme: theme });
+	// update the edited row when the user clicks the 'Save' button.
+	$("#Save").click(function () {
+		if (editrow >= 0) {
+			var rowID = $('#jqxgrid').jqxGrid('getrowid', editrow);
+			var row = {
+				record: rowID,
+				name: $("#name").val(),
+				address: $("#address").val(),
+				city: $("#city").val(),
+				zip: $("#zip").val(),
+				country: $("#country").val(),
+				website: $("#website").val(),
+				email: $("#email").val(),
+				phone: $("#phone").val(),
+				notes: $("#notes").val()
+			};
+			$('#jqxgrid').jqxGrid('updaterow', rowID, row);
+			$("#popupWindow").jqxWindow('hide');
+		} else {
+			// Insert a record
+			var newrow = {
+				record: -1,
+				name: $("#name").val(),
+				address: $("#address").val(),
+				city: $("#city").val(),
+				zip: $("#zip").val(),
+				country: $("#country").val(),
+				website: $("#website").val(),
+				email: $("#email").val(),
+				phone: $("#phone").val(),
+				notes: $("#notes").val()
+			};
+			$('#jqxgrid').jqxGrid('addrow', null, newrow);
+			$("#popupWindow").jqxWindow('hide');
+		}
+	});
+	createDelElements();
+});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/monitor.php	Sat Aug 11 22:49:44 2018 +0200
@@ -0,0 +1,356 @@
+<?php
+$my_style = 'android';
+require_once('version.php');
+?>
+<!DOCTYPE html>
+<html lang="en">
+ <head>'
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+  <title id='Description'>Brewery Managment System v<?php echo $my_version; ?></title>
+  <link type="text/css" href="css/style.css" rel="stylesheet" media="all" />
+  <link type="text/css" href="jqwidgets/styles/jqx.base.css" rel="stylesheet" />
+  <link type="text/css" href="jqwidgets/styles/jqx.<?php echo $my_style; ?>.css" rel="stylesheet" />
+  <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" />
+  <script src="js/jquery-1.11.1.min.js"></script>
+  <script src="jqwidgets/jqxcore.js"></script>
+  <script src="jqwidgets/jqxbuttons.js"></script>
+  <script src="jqwidgets/jqxscrollbar.js"></script>
+  <script src="jqwidgets/jqxpanel.js"></script>
+  <script src="jqwidgets/jqxtree.js"></script>
+  <script src="jqwidgets/jqxexpander.js"></script>
+  <script src="jqwidgets/jqxsplitter.js"></script>
+  <script src="jqwidgets/jqxdata.js"></script>
+  <script src="jqwidgets/jqxcheckbox.js"></script>
+  <script src="jqwidgets/jqxradiobutton.js"></script>
+  <script src="jqwidgets/jqxchart.core.js"></script>
+  <script src="jqwidgets/jqxgauge.js"></script>
+  <script src="jqwidgets/jqxdraw.js"></script>
+  <script src="jqwidgets/jqxtooltip.js"></script>
+  <script>
+  $(document).ready(function () {
+    /*
+     * Different right panel pages
+     */
+    var refreshIntervalId = 0;
+    $("#fermenter_thermometers").hide();
+    $("#splitter").jqxSplitter({ theme: "<?php echo $my_style; ?>", width: 1278, height: 618, panels: [{ size: 250}] });
+    $("#jqxTree").jqxTree({ theme: "<?php echo $my_style; ?>", height: "100%", width: "100%" });
+    /*
+     * Build the nodes subtree
+     */
+    var nodeByID = $("#jqxTree").find("#Nodes")[0];
+    $.getJSON("getnodes.php", function(data) {
+      for( i = 0; i < data.length; i++ ) {
+	 $("#jqxTree").jqxTree("addTo", { id: 'node-' + data[i].uuid, label: data[i].node, icon: 'images/folder.png'  }, nodeByID);
+      }
+    });
+    /*
+     * Build the fermenters subtree
+     */
+    var fermenterByID = $("#jqxTree").find("#Fermenters")[0];
+    $.getJSON("getfermenters.php", function(data) {
+      for( i = 0; i < data.length; i++ ) {
+        $("#jqxTree").jqxTree("addTo", { id: 'fermenter-' + data[i].uuid, label: data[i].node + "/" + data[i].alias, icon: 'images/folder.png' }, fermenterByID);
+      }
+    });
+
+    $("#jqxTree").css("visibility", "visible");
+
+    $("#jqxTree").on("select", function (event) {
+      /*
+       * Cancel a running refresh loop.
+       */
+      if (refreshIntervalId > 0) {
+	console.log( "RefreshIIntervald: " + refreshIntervalId + " stopped" );
+        clearInterval(refreshIntervalId);
+	refreshIntervalId = 0;
+      }
+      $("#fermenter_thermometers").hide();
+      $("#gaugeContainer_air").hide();
+      $("#gaugeContainer_beer").hide();
+      $("#gaugeContainer_chiller").hide();
+      /*
+       * Process the selected id from the left panel tree and show the correct page in the right panel.
+       */
+      var estr = event.args.element.id;
+      if (estr == "Root") {
+	$("#ContentPanel").html("<div style='margin: 10px;'><a href='index.php'>Hoofdmenu</a></div>");
+
+      } else if (estr.indexOf("node-", 0) == 0) {
+	// Load and show a node.
+	// The parameter is: node-36d4d030-4d62-4f2f-a96b-472e643687f7
+        var uuid = estr.substr(5);
+	var url = "getnode.php?uuid='" + uuid + "'";
+        var source = {
+          datatype: "json",
+          datafields: [
+            { name: 'record', type: 'int' },
+            { name: 'uuid', type: 'string' },
+            { name: 'node', type: 'string' },
+            { name: 'online', type: 'bool' },
+            { name: 'group_id', type: 'string' },
+            { name: 'hardwaremake', type: 'string' },
+            { name: 'hardwaremodel', type: 'string' },
+            { name: 'os', type: 'string' },
+            { name: 'os_version', type: 'string' },
+            { name: 'firmware', type: 'string' },
+            { name: 'firstseen', type: 'string' },
+            { name: 'lastseen', type: 'string' },
+            { name: 'temperature', type: 'float' },
+            { name: 'humidity', type: 'float' },
+            { name: 'barometer', type: 'float' },
+            { name: 'gps_latitude', type: 'float' },
+            { name: 'gps_longitude', type: 'float' },
+            { name: 'gps_altitude', type: 'float' },
+            { name: 'net_address', type: 'string' },
+            { name: 'net_ifname', type: 'string' },
+            { name: 'net_rssi', type: 'int' }
+          ],
+          id: 'record',
+          url: url
+        };
+	var dataAdapter = new $.jqx.dataAdapter(source, {
+	  loadComplete: function (records) {
+	    var record = dataAdapter.records[0];
+	    var html  = "<div style='background: #252526; margin: 50px;'>";
+	        html += "<table style='width: 100%; padding: 10px;'>";
+	        html += "<tr><th colspan=2>Systeem overzicht</th></tr>";
+                html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>";
+                html += "<tr><td>Systeem</td><td>" + record.node + "</td></tr>";
+	        html += "<tr><td>Online</td><td>" + record.online + "</td></tr>";
+		html += "<tr><td>Type</td><td>" + record.group_id + "</td></tr>";
+		html += "<tr><td>Eerst gezien</td><td>" + record.firstseen + "</td></tr>";
+		html += "<tr><td>Laatst gezien</td><td>" + record.lastseen + "</td></tr>";
+	        html += "<tr><td>Hardware maker</td><td>" + record.hardwaremake+ "</td></tr>";
+		html += "<tr><td>Hardware model</td><td>" + record.harwaremodel+ "</td></tr>";
+		html += "<tr><td>OS</td><td>" + record.os + " versie: " + record.os_version + "</td></tr>";
+		html += "<tr><td>Firmware</td><td>" + record.firmware + "</td></tr>";
+		if (record.online) {
+		  html += "<tr><td>Temperatuur</td><td>" + record.temperature + "&deg;C</td></tr>";
+		  if (record.humidity > 0) {
+		    html += "<tr><td>Vochtigheid</td><td>" + record.humidity + "%</td></tr>";
+		  }
+	          if (record.barometer > 0) {
+		    html += "<tr><td>Luchtdruk</td><td>" + record.barometer + "</td></tr>";
+		  }
+		  if ((record.gps_latitude != 0) && (record.gps_longitude != 0)) {
+		    html += "<tr><td>GPS</td><td>"+ record.gps_latitude + " " + record.gps_longitude + " " + record.gps_altitude + "</td></tr>";
+		  }
+		  html += "<tr><td>Netwerk</td><td>"+ record.net_ifname + " " + record.net_address + "</td></tr>";
+		}
+		html += "</<table>";
+	        html += "</div>";
+	    $("#ContentPanel").html(html);
+	  }
+	});
+	// Get the data immediatly and then at regular intervals to refresh.
+	dataAdapter.dataBind();
+	refreshIntervalId = setInterval(function(){
+          dataAdapter.dataBind();
+	}, 30000);
+
+      } else if (estr.indexOf("fermenter-", 0) == 0) {
+	// Load and show a fermenter.
+	// The parameter is: fermenter-36d4d030-4d62-4f2f-a96b-472e643687f7
+        var gaugeoptions = {
+	  min: -5, max: 35, width: 275, height: 275,
+	  ranges: [{ startValue: -5, endValue:  0, style: { fill: '#3399FF', stroke: '#3399FF' }, endWidth: 10, startWidth: 10 },
+	           { startValue:  0, endValue: 16, style: { fill: '#00CC33', stroke: '#00CC33' }, endWidth: 10, startWidth: 10 },
+	           { startValue: 16, endValue: 24, style: { fill: '#FCA76A', stroke: '#FCA76A' }, endWidth: 10, startWidth: 10 },
+	           { startValue: 24, endValue: 35, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }, endWidth: 10, startWidth: 10 }],
+	  ticksMinor: { interval: 1, size: '5%' },
+	  ticksMajor: { interval: 5, size: '9%' },
+	  labels: { interval: 5 },
+	  style: { fill: '#eeeeee', stroke: '#666666' },
+	  value: 0,
+	  colorScheme: 'scheme05',
+	  animationDuration: 1200
+        };
+	var gaugeSmalloptions = {
+	  min: -20, max: 25, width: 150, height: 150,
+	  ranges: [{ startValue: -20, endValue:  0, startWidth: 5, endWidth: 5, style: { fill: '#3399FF', stroke: '#3399FF' }},
+	           { startValue:   0, endValue: 25, startWidth: 5, endWidth: 5, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }}],
+	  ticksMinor: { interval: 1, size: '5%' },
+	  ticksMajor: { interval: 5, size: '9%' },
+	  labels: { interval: 5 },
+	  style: { fill: '#eeeeee', stroke: '#666666' },
+	  value: 0,
+	  colorScheme: 'scheme05',
+	  animationDuration: 1200,
+	  caption: { value: 'Chiller', position: 'bottom', offset: [0, 10] }
+	};
+	$("#fermenter_thermometers").show();
+	$("#gaugeContainer_air").show();
+	$("#gaugeContainer_air").jqxGauge( gaugeoptions );
+	$("#gaugeContainer_air").jqxGauge( { caption: { value: 'Air', position: 'bottom', offset: [0, 10] }} );
+	$("#gaugeContainer_beer").show();
+	$("#gaugeContainer_beer").jqxGauge( gaugeoptions );
+	$("#gaugeContainer_beer").jqxGauge( { caption: { value: 'Beer', position: 'bottom', offset: [0, 10] }} );
+	$("#gaugeContainer_chiller").show();
+	$("#gaugeContainer_chiller").jqxGauge( gaugeSmalloptions );
+	var uuid = estr.substr(10);
+	var url = "getfermenter.php?uuid='" + uuid + "'";
+	var source = {
+	  datatype: "json",
+	  datafields: [
+	    { name: 'record', type: 'int' },
+	    { name: 'uuid', type: 'string' },
+	    { name: 'alias', type: 'string' },
+	    { name: 'node', type: 'string' },
+	    { name: 'online', type: 'bool' },
+	    { name: 'beercode', type: 'string' },
+	    { name: 'beername', type: 'string' },
+	    { name: 'air_address', type: 'string' },
+	    { name: 'air_state', type: 'string' },
+	    { name: 'air_temperature', type: 'float' },
+	    { name: 'beer_address', type: 'string' },
+	    { name: 'beer_state', type: 'string' },
+ 	    { name: 'beer_temperature', type: 'float' },
+	    { name: 'chiller_address', type: 'string' },
+	    { name: 'chiller_state', type: 'string' },
+	    { name: 'chiller_temperature', type: 'float' },
+	    { name: 'heater_address', type: 'string' },
+	    { name: 'heater_state', type: 'int' },
+	    { name: 'heater_usage', type: 'int' },
+	    { name: 'cooler_address', type: 'string' },
+	    { name: 'cooler_state', type: 'int' },
+	    { name: 'cooler_usage', type: 'int' },
+	    { name: 'fan_address', type: 'string' },
+	    { name: 'fan_state', type: 'int' },
+	    { name: 'fan_usage', type: 'int' },
+	    { name: 'light_address', type: 'string' },
+	    { name: 'light_state', type: 'int' },
+	    { name: 'light_usage', type: 'int' },
+	    { name: 'door_address', type: 'string' },
+	    { name: 'door_state', type: 'int' },
+	    { name: 'psu_address', type: 'string' },
+	    { name: 'psu_state', type: 'int' },
+	    { name: 'mode', type: 'string' },
+	    { name: 'alarm', type: 'int' },
+	    { name: 'setpoint_high', type: 'float' },
+	    { name: 'setpoint_low', type: 'float' },
+	    { name: 'profile_uuid', type: 'string' },
+	    { name: 'profile_name', type: 'string' },
+	    { name: 'profile_state', type: 'string' },
+	    { name: 'profile_precent', type: 'int' },
+	    { name: 'profile_inittemp_high', type: 'float' },
+	    { name: 'profile_inittemp_low', type: 'float' },
+	    { name: 'profile_steps', type: 'string' },
+	    { name: 'stage', type: 'string' }
+    	  ],
+    	  id: 'record',
+          url: url
+	};
+        var dataAdapter = new $.jqx.dataAdapter(source, {
+	  loadComplete: function (records) {
+		  var record = dataAdapter.records[0];
+	    var oline = (record.online) ? "On-line" : "Off-line";
+	    var html  = "<div id='fermenter_table'>";
+	    html += "<table style='width: 100%; padding: 10px;'>";
+	    html += "<tr><th colspan=2>Klimaatkast overzicht</th></tr>";
+	    html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>";
+	    html += "<tr><td>Systeem</td><td>" + record.node +  "/" + record.alias + " " + oline + "</td></tr>";
+	    html += "<tr><td>Bier</td><td>" + record.beercode + " - " + record.beername + "</td></tr>";
+	    html += "<tr><td>Werking</td><td>" + record.mode + "</td></tr>";
+	    html += "<tr><td>Fase</td><td>" + record.stage + "</td></tr>"
+	    html += "</<table>";
+	    html += "</div>";
+	    $("#ContentPanel").html(html);
+	    $('#gaugeContainer_air').jqxGauge({ value: record.air_temperature });
+	    if (record.online && (record.air_state == "OK")) {
+	      $("#gaugeContainer_air").jqxGauge({ disabled: false });
+	    } else {
+	      $("#gaugeContainer_air").jqxGauge({ disabled: true });
+	    }
+	    $('#gaugeContainer_beer').jqxGauge({ value: record.beer_temperature });
+	    if (record.online && (record.beer_state == "OK")) {
+	      $("#gaugeContainer_beer").jqxGauge({ disabled: false });
+	    } else {
+	      $("#gaugeContainer_beer").jqxGauge({ disabled: true });
+	    }
+	    $("#gaugeContainer_chiller").jqxGauge({ value: record.chiller_temperature });
+	    if (record.online && (record.chiller_state == "OK")) {
+	      $("#gaugeContainer_chiller").jqxGauge({ disabled: false });
+	    } else {
+	      $("#gaugeContainer_chiller").jqxGauge({ disabled: true });
+	    }
+	    html  = "<div>SpH <span class='temperature NUM'>" + record.setpoint_high + "</span></div>";
+	    html += "<div>SpL <span class='temperature NUM'>" + record.setpoint_low + "</span></div>";
+	    html += "<div>Air <span class='temperature NUM'>" + record.air_temperature + "</span></div>";
+	    html += "<div>Beer <span class='temperature NUM'>" + record.beer_temperature + "</span></div>";
+	    $("#fermenter_tempdigits").html(html);
+	  }
+	});
+	// Get the data immediatly and then at regular intervals to refresh.
+	dataAdapter.dataBind();
+	refreshIntervalId = setInterval(function(){
+	  dataAdapter.dataBind();
+	}, 10000);
+
+      } else if (event.args.element.id == "Nodes") {
+        $("#ContentPanel").html("<div></div");
+      } else {
+        $("#ContentPanel").html("<div style='margin: 10px;'>" + event.args.element.id + "</div>");
+      }
+    });
+  });
+  </script>
+ </head>
+
+ <body class="default">
+  <div id="jqxWidget">
+   <div id="header">
+   <div id="title">BMS <?php echo $my_version; ?></div>
+   </div> <!-- header -->
+   <div id="splitter">
+    <div> <!-- tree panel -->
+     <div style="visibility: hidden; border: none;" id='jqxTree'>
+      <ul>
+       <li id="Root" item-expanded='true'>
+        <img style='float: left; margin-right: 5px;' src='images/earth.png' />
+        <span item-title="true">Root</span>
+        <ul>
+         <li id="Nodes">
+          <img style='float: left; margin-right: 5px;' src='images/folder.png' />
+          <span item-title="true">Systemen</span>
+          <!-- Subtree nodes -->
+         </li>
+         <li id="Fermenters">
+          <img style='float: left; margin-right: 5px;' src='images/folder.png' />
+          <span item-title="true">Klimaatkasten</span>
+          <!-- Subtree fermenters -->
+         </li>
+         <li id="Brewboards">
+          <img src='images/settings.png' />
+          <span item-title="true">Brouw apparatuur</span>
+         </li>
+         <li id="Prducing">
+          <img src='images/system.png' />
+          <span item-title="true">In productie</span>
+         </li>
+         <li id="Recipes">
+          <img style='float: left; margin-right: 5px;' src='images/beer.png' />
+          <span item-title="true">Recepten</span>
+         </li>
+         <li id="Settings">
+          <img style='float: left; margin-right: 5px;' src='images/setupIcon.png' />
+          <span item-title="true">Instellingen</span>
+         </li>
+        </ul>
+       </li>
+      </ul>
+     </div> <!-- jqxTree -->
+    </div> <!-- tree panel -->
+    <div id="RightPanel">
+     <div id="ContentPanel"></div>
+     <div id='fermenter_thermometers'>
+      <div id="gaugeContainer_air" style='float: left; margin-top: 10px; margin-left: 10px;'></div>
+      <div id="gaugeContainer_beer" style="float: right; margin-top: 10px; margin-right: 10px;"></div>
+      <div id="gaugeContainer_chiller" style="float: left; margin-top: 15px;"></div>
+      <div id="fermenter_tempdigits"></div>
+     </div>
+    </div>
+   </div> <!--- splitter -->
+  </div> <!-- jqxWidget -->
+ </body>
+</html>

mercurial