Rework the volume to the fermenter and things that depend on that. New layout on the brewday tab. The calculation model is simpler then the brouwhulp version.

Sat, 09 Feb 2019 15:43:13 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 09 Feb 2019 15:43:13 +0100
changeset 254
3d61397fe9cd
parent 253
296caca18161
child 255
28953f9fc5b4

Rework the volume to the fermenter and things that depend on that. New layout on the brewday tab. The calculation model is simpler then the brouwhulp version.

www/includes/db_product.php file | annotate | diff | comparison | revisions
www/js/prod_edit.js file | annotate | diff | comparison | revisions
www/js/prod_new.js file | annotate | diff | comparison | revisions
www/js/rec_edit.js file | annotate | diff | comparison | revisions
www/prod_edit.php file | annotate | diff | comparison | revisions
--- a/www/includes/db_product.php	Fri Feb 08 11:30:22 2019 +0100
+++ b/www/includes/db_product.php	Sat Feb 09 15:43:13 2019 +0100
@@ -100,8 +100,10 @@
 		$sql .= "', brew_aeration_type='" . $_POST['brew_aeration_type'];
 		$sql .= "', brew_fermenter_volume='" . $_POST['brew_fermenter_volume'];
 		$sql .= "', brew_fermenter_extrawater='" . $_POST['brew_fermenter_extrawater'];
+		$sql .= "', brew_fermenter_tcloss='" . $_POST['brew_fermenter_tcloss'];
 		$sql .= "', brew_fermenter_sg='" . $_POST['brew_fermenter_sg'];
 		$sql .= "', brew_fermenter_ibu='" . $_POST['brew_fermenter_ibu'];
+		$sql .= "', brew_fermenter_color='" . $_POST['brew_fermenter_color'];
 		if ($stage > 2) {
 			syslog(LOG_NOTICE, "write brewdate data end");
 			$sql .= "', brew_date_end='" . $_POST['brew_date_end'];
@@ -454,7 +456,6 @@
 	 */
 	if (isset($_GET['record'])) {
 		$query  = "SELECT * FROM products WHERE record='" . $_GET['record'] . "';";
-		syslog(LOG_NOTICE, "get products record " . $_GET['record']);
 	} else {
 		$query = "SELECT * FROM products ORDER BY birth,code;";
 	}
@@ -525,11 +526,13 @@
 		$brew .= ',"brew_whirlpool2":' . floatval($row['brew_whirlpool2']);
 		$brew .= ',"brew_fermenter_volume":' . floatval($row['brew_fermenter_volume']);
 		$brew .= ',"brew_fermenter_extrawater":' . floatval($row['brew_fermenter_extrawater']);
+		$brew .= ',"brew_fermenter_tcloss":' . floatval($row['brew_fermenter_tcloss']);
 		$brew .= ',"brew_aeration_time":' . floatval($row['brew_aeration_time']);
 		$brew .= ',"brew_aeration_speed":' . floatval($row['brew_aeration_speed']);
 		$brew .= ',"brew_aeration_type":' . $row['brew_aeration_type'];
 		$brew .= ',"brew_fermenter_sg":' . floatval($row['brew_fermenter_sg']);
 		$brew .= ',"brew_fermenter_ibu":' . floatval($row['brew_fermenter_ibu']);
+		$brew .= ',"brew_fermenter_color":' . floatval($row['brew_fermenter_color']);
 		$brew .= ',"brew_date_end":"' . $row['brew_date_end'];
 		$brew .= '","og":' . floatval($row['og']);
 		$brew .= ',"fg":' . floatval($row['fg']);
@@ -713,8 +716,6 @@
 		$brews .= $brew;
 	}
 	$brews .= ']';
-	if (isset($_GET['record']))
-		syslog(LOG_NOTICE, "ready to sent");
 	header("Content-type: application/json");
 	echo $brews;
 }
--- a/www/js/prod_edit.js	Fri Feb 08 11:30:22 2019 +0100
+++ b/www/js/prod_edit.js	Sat Feb 09 15:43:13 2019 +0100
@@ -48,13 +48,15 @@
 
 	var	to_100 = false;		// Fermentables adjust to 100%
 	var     preboil_sg = 0;
+	var	aboil_sg = 0;
 	var	est_mash_sg = 0;
 	var     sugarsm = 0;		// Sugars after mash
-	var     sugarsf = 0;		// Sugars after boil
+	var     sugarsf = 0;		// Sugars after boil in kettle
 	var     psugar = 0;		// Percentage real sugars
 	var     pcara = 0;		// Percentage cara/crystal malts
 	var     svg = 77;               // Default attenuation
         var     mashkg = 0;             // Malt in mash weight
+
         var     hop_flavour = 0;
         var     hop_aroma = 0;
         var     mash_infuse = 0;
@@ -97,17 +99,38 @@
                 theme: theme
         });
 
+	/*
+	 * All calculations that depend on changes in the fermentables,
+	 * volumes and equipments.
+	 */
 	function calcFermentables() {
+
 		console.log("calcFermentables()");
-		sugarsf = 0;
-		sugarsm = 0;
+		sugarsf = 0;	// fermentable sugars mash + boil
+		sugarsm = 0;	// fermentable sugars in mash
 		psugar = 0;
 		pcara = 0;
 		mashkg = 0;
-		var colorw = 0; // Colors working
+		var vol = 0;		// Volume sugars after boil
+		var addedS = 0;		// Added sugars after boil
+		var addedmass = 0;	// Added mass after boil
+		var mvol = 0;		// mash volume
+		var colort = 0;		// Colors srm * vol totals
 		var my_100 = false;
 
-                var rows = $('#fermentableGrid').jqxGrid('getrows');
+		if ((rows = $('#mashGrid').jqxGrid('getrows'))) {
+			for (var i = 0; i < rows.length; i++) {
+				var row = rows[i];
+				if (row.step_type == 0) // Infusion
+					mvol += parseFloat(row.step_infuse_amount);
+			}
+		}
+
+		if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) {
+			return; // grid not yet loaded.
+		}
+
+		var s = 0;
                 for (var i = 0; i < rows.length; i++) {
                         var row = rows[i];
                         if (row.f_adjust_to_total_100)
@@ -118,12 +141,23 @@
 				pcara += row.f_percentage;
 			var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100);
 			if (row.f_added == 0) {	// Mash
+				if (mvol > 0) {	// Only if mash already known.
+					mvol += row.f_amount * row.f_moisture / 100;
+					s += d;
+				}
 				d = parseFloat(dataRecord.efficiency) / 100 * d;
 				sugarsm += d;
 				mashkg += row.f_amount;
 			}
-			sugarsf += d;
-			colorw += row.f_amount * ebc_to_srm(row.f_color) / parseFloat(dataRecord.batch_size) * 8.34436;
+			if (row.f_added == 0 || row.f_added == 1)	// Mash or Boil
+				sugarsf += d;
+			if (row.f_added == 2 || row.f_added == 3) {
+				var x = (row.f_yield / 100) * (1 - row.f_moisture / 100);
+				addedS += row.f_amount * x;
+				addedmass += row.f_amount;
+				vol += (x * sugardensity + (1 - x) * 1) * row.f_amount;
+			}
+			colort += row.f_amount * ebc_to_srm(row.f_color);
 		}
 		to_100 = my_100;
 		if (to_100) {
@@ -131,93 +165,126 @@
 		} else {
 			$("#wf_amount").jqxNumberInput({ width: 110, readOnly: false, spinButtons: true });
 		}
-		var est_og = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size));
-		dataRecord.est_og = est_og;
-                $('#est_og').val(est_og);
-                $('#est_og2').val(est_og);
-		$('#est_og3').val(est_og);
+
+		if (mvol > 0) {
+			var v = s / sugardensity + mvol;
+			s = 1000 * s / (v * 10); //deg. Plato
+			est_mash_sg = Math.round(plato_to_sg(s) * 1000) / 1000;
+			//console.log("est_mash_sg "+est_mash_sg);
+			$('#est_mash_sg').val(est_mash_sg);
+		}
+
+		// Estimate total recipe OG.
+		dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size));
+                $('#est_og').val(dataRecord.est_og);
+                $('#est_og2').val(dataRecord.est_og);
+
+		// Estimate SG in kettle after boil
+		aboil_sg = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size));
+		$('#est_og3').val(aboil_sg);
+
+		// Estimate SG in kettle before boil
 		preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size));
 		$('#est_pre_sg').val(preboil_sg);
-		var color = kw_to_ebc(dataRecord.color_method, colorw);
+
+		// Recalculate volumes.
+		var aboil_volume = parseFloat(dataRecord.batch_size);
+		if (dataRecord.brew_aboil_volume > 0)
+			aboil_volume = dataRecord.brew_aboil_volume / 1.04;	// volume @ 20 degrees
+		dataRecord.brew_fermenter_volume = aboil_volume - dataRecord.brew_fermenter_tcloss + dataRecord.brew_fermenter_extrawater;
+		$("#brew_fermenter_volume").val(dataRecord.brew_fermenter_volume);
+
+		// Calculate SG in fermenter
+		var ogx = dataRecord.brew_aboil_sg;
+		if (ogx < 1.002)
+			ogx = aboil_sg;
+		var top = dataRecord.brew_fermenter_extrawater;
+
+		if (dataRecord.brew_fermenter_volume > 0) {
+			var sug = sg_to_plato(ogx) * dataRecord.brew_fermenter_volume * ogx / 100;  //kg of sugar in
+			sug += addedS; //kg
+			console.log("Contents ferm_vol:"+dataRecord.brew_fermenter_volume+" top:"+top+" vol:"+vol+" addedS:"+addedS+" addedmass:"+addedmass);
+
+			if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) {
+				var pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + top);
+				dataRecord.brew_fermenter_sg = Math.round(plato_to_sg(pt) * 1000) / 1000;
+				$("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg);
+				// color
+				var cw = colort / (aboil_volume + top) * 8.34436;
+				dataRecord.brew_fermenter_color = kw_to_ebc(dataRecord.color_method, cw);
+				$("#brew_fermenter_color").val(dataRecord.brew_fermenter_color);
+				var scolor = ebc_to_color(dataRecord.brew_fermenter_color);
+				$("#bcolorf").show();
+				document.getElementById("bcolorf").style.background= scolor;
+				console.log("OG in fermenter:"+dataRecord.brew_fermenter_sg+" color:"+dataRecord.brew_fermenter_color);
+			}
+		} else {
+			// Negative volume
+			dataRecord.brew_fermenter_sg = dataRecord.brew_fermenter_color = 0;
+			$("#brew_fermenter_sg").val(0);
+			$("#brew_fermenter_color").val(0);
+			$("#bcolorf").hide();
+		}
+
+		// Color of the wort
+		var cw = colort / parseFloat(dataRecord.batch_size) * 8.34436;
+		var color = kw_to_ebc(dataRecord.color_method, cw);
 		dataRecord.est_color = color;
                 $('#est_color').val(color);
                 $('#est_color2').val(color);
                 var scolor = ebc_to_color(color);
                 document.getElementById("bcolor").style.background= scolor;
                 document.getElementById("bcolor2").style.background= scolor;
+
+		// Progress bars
                 pmalts = mashkg / dataRecord.eq_mash_max * 100;
-//		console.log("mash kg: "+mashkg+" max: "+dataRecord.eq_mash_max+" perc: "+pmalts);
+		//console.log("mash kg: "+mashkg+" max: "+dataRecord.eq_mash_max+" perc: "+pmalts);
                 $("#perc_malts").jqxProgressBar('val', pmalts);
                 $("#perc_sugars").jqxProgressBar('val', psugar);
                 $("#perc_cara").jqxProgressBar('val', pcara);
 		calcStage();
 	};
 
+	/*
+	 * Change OG of recipe but keep the water volumes.
+	 */
 	function calcFermentablesFromOG(OG) {
 
 		console.log("calcFermentablesFromOG("+OG+")");
-		var     i, j, sug, d, tot, totmass;
-		var     vol, vol1, vol2, sug2;
-		var     mass1, mass2, efficiency;
+		var efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal'));
+		var sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100;      //total amount of sugars in kg
+		var tot = 0;
+		var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount;
 
-		for (j = 1; j < 15; j++) {
-			vol = 0;
-			sug2 = 0;
-			efficiency = parseFloat(dataRecord.efficiency);
-			var rows = $('#fermentableGrid').jqxGrid('getrows');
-			for (i = 0; i < rows.length; i++) {
-				var row = rows[i];
-				if ((row.f_added == 2) || (row.f_added == 3) || (row.f_added == 4)) {	// Fermentation, Lagering or Bottle
-					var x = (row.f_yield / 100) * (1 - row.f_moisture / 100);
-					vol += row.f_amount / (x * sugardensity + (1 - x) * 1);
-					sug2 += row.f_amount * x;
-				}
+		for (var i = 0; i < rowscount; i++) {
+			var row = $("#fermentableGrid").jqxGrid('getrowdata', i);
+			var d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100);
+			if (row.f_added == 0)	// Mash
+				d = efficiency / 100 * d;
+			tot += d;
+		}
+		var totmass = 0;
+		if (tot)
+			totmass = sug / tot;
+
+		if (totmass) {
+			for (i = 0; i < rowscount; i++) {
+				var row = $("#fermentableGrid").jqxGrid('getrowdata', i);
+				var amount = row.f_percentage / 100 * totmass;
+				$("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", amount);
 			}
-			sug = sg_to_plato(OG) * OG / 100;	// kg/l
-			vol1 = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss;
-			vol2 = vol1 + dataRecord.eq_top_up_water + vol;
-			sug = sug * vol2;	// kg in het gistvat
-			sug = sug - sug2;	// kg voor toevoeging in gistvat
-			if (vol1 > 0)
-				sug = sug * dataRecord.batch_size / vol1;	//kg in kookketel
-			sug = sug + sug2;
-			//	sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100;      //total amount of sugars in kg
-
-			tot = 0;
-			d = 0;
-			for (i = 0; i < rows.length; i++) {
-				var row = rows[i];
-				d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100);
-				if (row.f_added == 0)	// Mash
-					d = efficiency / 100 * d;
-				tot += d;
-			}
-			if (tot)
-				totmass = sug / tot;
-			else
-				totmass = 0;
-
-			if (totmass) {
-				console.log("pass:"+j+" totmass:"+totmass);
-				for (i = 0; i < rows.length; i++) {
-					var row = rows[i];
-					row.f_amount = row.f_percentage / 100 * totmass;
-					$("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", row.f_percentage / 100 * totmass);
-				}
-			}
-		};
-		//CalcWaterBalance;
+		}
 	};
 
 	function calcFG() {
-		var fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, parseFloat(parseFloat($("#est_og").jqxNumberInput('decimal'))));
+		var fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og);
 		dataRecord.est_fg = fg;
 		$('#est_fg').val(fg);
 		$('#est_fg2').val(fg);
 	}
 
 	function calcABV() {
-		var abv = abvol(parseFloat($("#est_og").jqxNumberInput('decimal')), parseFloat($("#est_fg").jqxNumberInput('decimal')));
+		var abv = abvol(dataRecord.est_og, dataRecord.est_fg);
 		$("#est_abv").val(abv);
 		$("#est_abv2").val(abv);
 	};
@@ -292,36 +359,6 @@
 		}
 	}
 
-	function calcSGendMash() {
-		est_mash_sg = 0;
-		var	mvol = 0;	// Mash volume
-		var	s = 0;
-		var	gs = 0;		// Grain absorbtion
-		var rows = $('#mashGrid').jqxGrid('getrows');
-		for (var i = 0; i < rows.length; i++) {
-			var row = rows[i];
-			if (row.step_type == 0)	// Infusion
-				mvol += parseFloat(row.step_infuse_amount);
-		}
-		if (mvol > 0) {
-			var rows = $('#fermentableGrid').jqxGrid('getrows');
-			for (var i = 0; i < rows.length; i++) {
-			        var row = rows[i];
-				if (row.f_added == 0) {	// Mash
-					var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100);
-					mvol += row.f_amount * row.f_moisture / 100;
-//  TODO: where do I need this		gs += my_grain_absorbtion * row.f_amount;
-					s += d;
-				}
-			}
-			var v = s / sugardensity + mvol;
-			s = 1000 * s / (v * 10); //deg. Plato
-			est_mash_sg = plato_to_sg(s);
-		}
-		console.log("calcSGendMash(): " + est_mash_sg);
-		$('#est_mash_sg').val(est_mash_sg);
-	};
-
 	function calcMashEfficiency() {
 //		console.log("calcMashEfficiency()");
 		var c = sg_to_plato(est_mash_sg);
@@ -399,7 +436,7 @@
 	}
 
 	function setWaterAgent(name, amount) {
-		console.log("setWaterAgent(" + name + ", " + amount + ")");
+		//console.log("setWaterAgent(" + name + ", " + amount + ")");
 		var rows = $('#miscGrid').jqxGrid('getrows');
 		if (amount == 0) {
 			for (var i = 0; i < rows.length; i++) {
@@ -1236,7 +1273,6 @@
 	function calcInit () {
 		console.log("calcInit()");
 
-		calcSGendMash();
 		calcMashEfficiency();
 		calcEfficiencyBeforeBoil();
 		calcEfficiencyAfterBoil();
@@ -1388,7 +1424,6 @@
 		$('#est_og').on('change', function (event) {
 			console.log("est_og change:"+event.args.value);
 			$('#est_og2').val(event.args.value);
-			$('#est_og3').val(event.args.value);
 			calcFermentablesFromOG(event.args.value);       // Adjust fermentables amounts
 			calcFermentables();                             // Update the recipe details
 			calcSVG();
@@ -1468,6 +1503,15 @@
 			calcCarbonation();
 		});
 
+		$("#brew_fermenter_extrawater").on('change', function (event) {
+			dataRecord.brew_fermenter_extrawater = parseFloat(event.args.value);
+			calcFermentables();
+		});
+		$("#brew_fermenter_tcloss").on('change', function (event) {
+			dataRecord.brew_fermenter_tcloss = parseFloat(event.args.value);
+			calcFermentables();
+		});
+
 		$("#BLog").jqxButton({ disabled: (dataRecord.log_brew) ? false:true });
 		$("#FLog").jqxButton({ disabled: (dataRecord.log_fermentation) ? false:true });
 	};
@@ -1641,11 +1685,13 @@
 			{ name: 'brew_whirlpool2', type: 'float' },
 			{ name: 'brew_fermenter_volume', type: 'float' },
 			{ name: 'brew_fermenter_extrawater', type: 'float' },
+			{ name: 'brew_fermenter_tcloss', type: 'float' },
 			{ name: 'brew_aeration_time', type: 'float' },
 			{ name: 'brew_aeration_speed', type: 'float' },
 			{ name: 'brew_aeration_type', type: 'int' },
 			{ name: 'brew_fermenter_sg', type: 'float' },
 			{ name: 'brew_fermenter_ibu', type: 'float' },
+			{ name: 'brew_fermenter_color', type: 'float' },
 			{ name: 'brew_date_end', type: 'string' },
 			{ name: 'og', type: 'float' },
 			{ name: 'fg', type: 'float' },
@@ -1811,6 +1857,9 @@
 			$("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg);
 			$("#brew_fermenter_sg2").val(dataRecord.brew_fermenter_sg);
 			$("#brew_fermenter_ibu").val(dataRecord.brew_fermenter_ibu);
+			$("#brew_fermenter_color").val(dataRecord.brew_fermenter_color);
+			$("#brew_fermenter_extrawater").val(dataRecord.brew_fermenter_extrawater);
+			$("#brew_fermenter_tcloss").val(dataRecord.brew_fermenter_tcloss);
 
 			$("#brew_aboil_ph").val(dataRecord.brew_aboil_ph);
 			$("#brew_aboil_sg").val(dataRecord.brew_aboil_sg);
@@ -1821,10 +1870,6 @@
 			$("#brew_cooling_method").val(dataRecord.brew_cooling_method);
 			$("#brew_cooling_time").val(dataRecord.brew_cooling_time);
 			// Niks
-			// Header Naar gistvat
-			$("#brew_fermenter_extrawater").val(dataRecord.brew_fermenter_extrawater);
-			$("#brew_fermenter_extrasugar").val(dataRecord.brew_fermenter_extrasugar);
-			$("#brew_fermenter_color").val(dataRecord.brew_fermenter_color);
 			$("#brew_date_end").val(dataRecord.brew_date_end);
 			$("#og").val(dataRecord.og);
 			$("#fg").val(dataRecord.fg);
@@ -1890,7 +1935,7 @@
 			$("#efficiency").val(dataRecord.efficiency);
 			$("#est_og").val(dataRecord.est_og);
 			$("#est_og2").val(dataRecord.est_og);
-			$("#est_og3").val(dataRecord.est_og);
+			$("#est_og3").val(0);
 			$("#est_fg").val(dataRecord.est_fg);
 			$("#est_fg2").val(dataRecord.est_fg);
 			$("#est_color").val(dataRecord.est_color);
@@ -2873,17 +2918,6 @@
         };
 
 	// initialize the input fields.
-//        var srcType = [ "All Grain", "Partial Mash", "Extract" ];
-        var srcColor = [ "Morey", "Mosher", "Daniels" ];
-        var srcIBU = [ "Tinseth", "Rager", "Daniels" ]; // Only these are supported at this time.
-        var srcBase = [ "NaHCO3", "Na2CO3", "CaCO3", "Ca(OH)2" ];
-        var srcAcid = [ "Melkzuur", "Zoutzuur", "Fosforzuur", "Zwavelzuur" ];
-	var srcSource = [ "Bron 1", "Bron 2", "Gemengd" ];
-	var srcSugar = [ "Kristalsuiker", "Glucose/dextrose", "Honing", "Moutextract", "Melasse" ];
-	var srcMaterial= [ "RVS", "Aluminium", "Kunststof", "Koper" ];
-	var srcAeration= [ 'None', 'Air', 'Oxygen' ];
-	var srcCooling= [ '-', 'Emersion chiller', 'Counterflow chiller', 'Au bain marie', 'Natural' ];
-	//                '-', 'Dompelkoeler', 'Tegenstroomkoeler', 'Au bain marie', 'Laten afkoelen'
 	// Tab 1, Algemeen
 	$("#name").jqxTooltip({ content: 'De naam voor dit product.' });
 	$("#name").jqxInput({ theme: theme, width: 640, height: 23 });
@@ -3241,6 +3275,13 @@
 		autoDropDownHeight: true,
 		dropDownVerticalAlignment: 'top'
 	});
+	$("#wf_added").on('select', function (event) {
+		if (event.args) {
+			var index = event.args.index;
+			$("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_added', index);
+			calcFermentables();
+		}
+	});
 
 	// Tab 4, Hops
 	$("#est_ibu2").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' });
@@ -3957,19 +3998,19 @@
 	$("#est_pre_sg").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 3 });
 	$("#brew_aboil_sg").jqxTooltip({ content: 'Het gemeten SG in de kookketel na het koken.' });
 	$("#brew_aboil_sg").jqxNumberInput( SGopts );
-	$("#brew_aboil_sg").on('valueChanged', function (event) { dataRecord.brew_aboil_sg = event.args.value; calcEfficiencyAfterBoil() });
+	$("#brew_aboil_sg").on('valueChanged', function (event) { dataRecord.brew_aboil_sg = event.args.value; calcEfficiencyAfterBoil(); calcFermentables(); });
 	$("#est_og3").jqxTooltip({ content: 'Het gewenste SG in de kookketel na het koken.' });
 	$("#est_og3").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 70, height: 23, decimalDigits: 3, readOnly: true });
 	$("#brew_mash_efficiency").jqxTooltip({ content: 'Het behaalde maisch rendement.' });
 	$("#brew_mash_efficiency").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 90, height: 23, decimalDigits: 1 });
-	$("#brew_preboil_volume").jqxTooltip({ content: 'Het volume van het wort voor het koken.' });
+	$("#brew_preboil_volume").jqxTooltip({ content: 'Het gemeten volume van het wort voor het koken.' });
 	$("#brew_preboil_volume").jqxNumberInput( Spin1dec );
 	$("#brew_preboil_volume").on('valueChanged', function (event) { dataRecord.brew_preboil_volume = event.args.value; calcEfficiencyBeforeBoil() });
 	$("#est_pre_vol").jqxTooltip({ content: 'Het berekende volume van het wort voor het koken.' });
 	$("#est_pre_vol").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 1 });
-	$("#brew_aboil_volume").jqxTooltip({ content: 'Het volume van het wort na het koken.' });
+	$("#brew_aboil_volume").jqxTooltip({ content: 'Het gemeten volume van het wort na het koken.' });
 	$("#brew_aboil_volume").jqxNumberInput( Spin1dec );
-	$("#brew_aboil_volume").on('valueChanged', function (event) { dataRecord.brew_aboil_volume = event.args.value; calcEfficiencyAfterBoil() });
+	$("#brew_aboil_volume").on('valueChanged', function (event) { dataRecord.brew_aboil_volume = event.args.value; calcEfficiencyAfterBoil(); calcFermentables(); });
 	$("#est_a_vol").jqxTooltip({ content: 'Het gewenste volume na het koken.' });
 	$("#est_a_vol").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 1 });
 	$("#brew_preboil_efficiency").jqxTooltip({ content: 'Het berekende rendement voor het koken.' });
@@ -4012,10 +4053,10 @@
 	$("#brew_aeration_time").jqxNumberInput({ max: 1440 });
 	$("#brew_aeration_speed").jqxNumberInput( PosInt );
 	$("#brew_aeration_speed").jqxNumberInput({ max: 1440 });
-	$("#brew_fermenter_volume").jqxNumberInput( Spin1dec );
+	$("#brew_fermenter_volume").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 90, height: 23, decimalDigits: 1 });
 	$("#brew_fermenter_extrawater").jqxNumberInput( Spin1dec );
 	$("#brew_fermenter_sg").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 90, height: 23, decimalDigits: 3 });
-	$("#brew_fermenter_extrasugar").jqxNumberInput( Spin1dec );
+	$("#brew_fermenter_tcloss").jqxNumberInput( Spin1dec );
 	$("#brew_fermenter_ibu").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 90, height: 23, decimalDigits: 0 });
 	$("#brew_fermenter_color").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 90, height: 23, decimalDigits: 0 });
 	$("#BLog").jqxButton({ template: "info", width: '150px', theme: theme });
@@ -4239,11 +4280,13 @@
 			brew_whirlpool2: parseFloat($("#brew_whirlpool2").jqxNumberInput('decimal')),
 			brew_fermenter_volume: parseFloat($("#brew_fermenter_volume").jqxNumberInput('decimal')),
 			brew_fermenter_extrawater: parseFloat($("#brew_fermenter_extrawater").jqxNumberInput('decimal')),
+			brew_fermenter_tcloss: parseFloat($("#brew_fermenter_tcloss").jqxNumberInput('decimal')),
 			brew_aeration_time: parseFloat($("#brew_aeration_time").jqxNumberInput('decimal')),
 			brew_aeration_speed: parseFloat($("#brew_aeration_speed").jqxNumberInput('decimal')),
 			brew_aeration_type: $("#brew_aeration_type").val(),
 			brew_fermenter_sg: parseFloat($("#brew_fermenter_sg").jqxNumberInput('decimal')),
 			brew_fermenter_ibu: parseFloat($("#brew_fermenter_ibu").jqxNumberInput('decimal')),
+			brew_fermenter_color: parseFloat($("#brew_fermenter_color").jqxNumberInput('decimal')),
 			brew_date_end: $("#brew_date_end").val(),
 			og: dataRecord.og,
 			fg: parseFloat($("#fg").jqxNumberInput('decimal')),
--- a/www/js/prod_new.js	Fri Feb 08 11:30:22 2019 +0100
+++ b/www/js/prod_new.js	Sat Feb 09 15:43:13 2019 +0100
@@ -290,28 +290,31 @@
 					brew_sparge_volume: 0,
 					brew_sparge_ph: 0.0,
 					brew_preboil_volume: 0,
-					brew_preboil_sg: 1.000,
+					brew_preboil_sg: 0,
 					brew_preboil_ph: 0.0,
 					brew_aboil_volume: 0,
-					brew_aboil_sg: 1.000,
+					brew_aboil_sg: 0,
 					brew_aboil_ph: 0.0,
 					brew_aboil_efficiency: 0,
 					brew_cooling_method: 0,
 					brew_cooling_time: 0,
-					brew_cooling_to: 0,
+					brew_cooling_to: 20,
 					brew_whirlpool9: 0,
 					brew_whirlpool7: 0,
 					brew_whirlpool6: 0,
 					brew_whirlpool2: 0,
-					brew_fermenter_volume: 0,
-					brew_fermenter_extrawater: 0,
+					brew_fermenter_volume: parseFloat($("#eq_batch_size").jqxNumberInput('decimal')) -
+							parseFloat($("#eq_trub_chiller_loss").jqxNumberInput('decimal')) +
+							parseFloat($("#eq_top_up_water").jqxNumberInput('decimal')),
+					brew_fermenter_extrawater: parseFloat($("#eq_top_up_water").jqxNumberInput('decimal')),
+					brew_fermenter_tcloss: parseFloat($("#eq_trub_chiller_loss").jqxNumberInput('decimal')),
 					brew_aeration_time: 0,
 					brew_aeration_speed: 0,
 					brew_aeration_type: 0,
 					brew_fermenter_sg: 0,
 					brew_fermenter_ibu: 0,
+					brew_fermenter_color: 0,
 					brew_date_end: '',
-					brew_log_available: false,
 					og: 0,
 					fg: 0,
 					primary_start_temp: 0,
--- a/www/js/rec_edit.js	Fri Feb 08 11:30:22 2019 +0100
+++ b/www/js/rec_edit.js	Sat Feb 09 15:43:13 2019 +0100
@@ -989,32 +989,35 @@
 		$("#sparge_acid_amount").val(Acid);
 	}
 
+	/*
+	 * Change OG of recipe but keep the water volumes.
+	 */
 	function calcFermentablesFromOG(OG) {
 
 		console.log("calcFermentablesFromOG("+OG+")");
-		var	efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal'));
-		var	rows = $('#fermentableGrid').jqxGrid('getrows');
-		var	sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100;	//total amount of sugars in kg
-		var	tot = 0;
-		for (var i = 0; i < rows.length; i++) {
-			var row = rows[i];
+		var efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal'));
+		var sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100;	//total amount of sugars in kg
+		var tot = 0;
+		var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount;
+
+		for (var i = 0; i < rowscount; i++) {
+			var row = $("#fermentableGrid").jqxGrid('getrowdata', i);
 			var d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100);
 			if (row.f_added == 0)	// Mash
 				d = efficiency / 100 * d;
 			tot += d;
 		}
-
 		var	totmass = 0;
 		if (tot)
 			totmass = sug / tot;
 
 		if (totmass) {
-			for (var i = 0; i < rows.length; i++) {
-				var row = rows[i];
-				$("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", row.f_percentage / 100 * totmass);
+			for (i = 0; i < rowscount; i++) {
+				var row = $("#fermentableGrid").jqxGrid('getrowdata', i);
+				var amount = row.f_percentage / 100 * totmass;
+				$("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", amount);
 			}
 		}
-		//CalcWaterBalance;
 	};
 
 	function calcFG() {
--- a/www/prod_edit.php	Fri Feb 08 11:30:22 2019 +0100
+++ b/www/prod_edit.php	Sat Feb 09 15:43:13 2019 +0100
@@ -516,24 +516,24 @@
       <tr>
        <td style="vertical-align: top; float: right;">Beluchten snelheid:</td>
        <td><div id="brew_aeration_speed"></div></td>
-       <td style="vertical-align: top; float: right;">Volume naar gistvat:</td>
-       <td><div id="brew_fermenter_volume"></div></td>
-       <td style="vertical-align: top; float: right;">Extra water:</td>
-       <td><div id="brew_fermenter_extrawater"></div></td>
+       <td style="vertical-align: top; float: right;">Trub Chiller loss:</td>
+       <td><div id="brew_fermenter_tcloss"></div></td>
+       <td style="vertical-align: top; float: right;">SG in gistvat:</td>
+       <td><div id="brew_fermenter_sg"></div></td>
       </tr>
       <tr>
        <td colspan="2"> </td>
-       <td style="vertical-align: top; float: right;">SG in gistvat:</td>
-       <td><div id="brew_fermenter_sg"></div></td>
-       <td style="vertical-align: top; float: right;">Extra suiker:</td>
-       <td><div id="brew_fermenter_extrasugar"></div></td>
+       <td style="vertical-align: top; float: right;">Extra water:</td>
+       <td><div id="brew_fermenter_extrawater"></div></td>
+       <td style="vertical-align: top; float: right;">Kleur in gistvat:</td>
+       <td><div style="float: left;" id="brew_fermenter_color"></div><div style="float: left; margin-left: 15px;" id="bcolorf" class='ebccolor'> </div></td>
       </tr>
       <tr>
        <td colspan="2"> </td>
+       <td style="vertical-align: top; float: right;">Volume naar gistvat:</td>
+       <td><div id="brew_fermenter_volume"></div></td>
        <td style="vertical-align: top; float: right;">IBU in gistvat:</td>
-       <td><div style="float: left;" id="brew_fermenter_ibu"></div><div style="float: left; margin-left: 35px;" id="est_ibu"></div></td>
-       <td style="vertical-align: top; float: right;">Kleur in gistvat:</td>
-       <td><div style="float: left;" id="brew_fermenter_color"></div><div style="float: left; margin-left: 35px;" id="est_color"></div></td>
+       <td><div style="float: left;" id="brew_fermenter_ibu"></div></td>
       </tr>
      </table>
      <div style="float: right; margin-top: 20px; margin-bottom: 5px;">

mercurial