Fixed estimate_fg formula. Estimate neede sparge water displayed on the brewday tab. Moved calcSVG, calcFG and calcABV functions into calcFermentables. Calc FG now uses mash data if available. Show estimated fg on the fermentation tab. Cosmetic changes on the brewday tab.

Sun, 10 Feb 2019 16:14:48 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 10 Feb 2019 16:14:48 +0100
changeset 258
943fbe0e9fd6
parent 257
62e294ab94f5
child 259
ffab9ba3f532

Fixed estimate_fg formula. Estimate neede sparge water displayed on the brewday tab. Moved calcSVG, calcFG and calcABV functions into calcFermentables. Calc FG now uses mash data if available. Show estimated fg on the fermentation tab. Cosmetic changes on the brewday tab.

www/js/global.js file | annotate | diff | comparison | revisions
www/js/prod_edit.js file | annotate | diff | comparison | revisions
www/prod_edit.php file | annotate | diff | comparison | revisions
--- a/www/js/global.js	Sat Feb 09 22:12:31 2019 +0100
+++ b/www/js/global.js	Sun Feb 10 16:14:48 2019 +0100
@@ -998,8 +998,14 @@
 		percCara = 0;
 	if ((WGratio > 0) && (TotTme > 0)) {
 		BD = WGratio;
-		BD = max(2, min(5.5, BD));
-		Temp = max(60, min(72, Temp));
+		if (BD < 2)
+			BD = 2;
+		if (BD > 5.5)
+			BD = 5.5;
+		if (Temp < 60)
+			Temp = 60;
+		if (Temp > 72)
+			Temp = 72;
 	} else {
 		BD = 3.5;
 		Temp = 67;
@@ -1009,9 +1015,9 @@
 		attenuation = 77;
 
 	var AttBeer = 0.00825 * attenuation + 0.00817 * BD - 0.00684 * Temp + 0.00026 * TotTme - 0.00356 * percCara + 0.00553 * percSugar + 0.547;
-	var fg = Math.round((1 + (1 - AttBeer) * (og - 1)) * 1000) / 1000;
+	var fg = Math.round((1 + (1 - AttBeer) * (og - 1)) * 10000) / 10000;
 
-	console.log("estimate_fg("+percSugar+","+percCara+","+WGratio+","+TotTme+","+Temp+","+attenuation+","+og+") :"+fg);
+	//console.log("estimate_fg("+percSugar+","+percCara+","+BD+","+TotTme+","+Temp+","+attenuation+","+og+") :"+fg);
 	return fg;
 }
 
--- a/www/js/prod_edit.js	Sat Feb 09 22:12:31 2019 +0100
+++ b/www/js/prod_edit.js	Sun Feb 10 16:14:48 2019 +0100
@@ -115,13 +115,19 @@
 		var mvol = 0;		// mash volume
 		var colort = 0;		// Colors srm * vol totals
 		var my_100 = false;
+		var mashtime = 0;	// Total mash time
+		var mashtemp = 0;	// Average mash temperature
 
 		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);
+				mashtime += row.step_time;
+				mashtemp += row.step_time * row.step_temp;
 			}
+			mashtemp = mashtemp / mashtime;
+			console.log("mash time:"+mashtime+" temp:"+mashtemp);
 		}
 
 		if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) {
@@ -191,6 +197,9 @@
 			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);
+		// Estimated needed sparge water corrected for the temperature.
+		var spoelw = (dataRecord.boil_size - mash_infuse + (mashkg * my_grain_absorbtion) + dataRecord.eq_lauter_deadspace) * 1.03;
+		$("#brew_sparge_est").val(spoelw);
 
 		// Calculate SG in fermenter
 		var ogx = dataRecord.brew_aboil_sg;
@@ -241,6 +250,35 @@
                 $("#perc_sugars").jqxProgressBar('val', psugar);
                 $("#perc_cara").jqxProgressBar('val', pcara);
 		calcStage();
+
+		// Calculate estimated svg.
+		svg = 77; // default.
+		var rows = $('#yeastGrid').jqxGrid('getrows');
+		for (var i = 0; i < rows.length; i++) {
+			var row = rows[i];
+			if (row.y_use == 0)     // Primary
+				svg = parseFloat(row.y_attenuation);
+		}
+
+		if ((mashkg > 0) && (mash_infuse > 0) && (mashtime > 0) && (mashtemp > 0)) {
+			dataRecord.est_fg = estimate_fg(psugar, pcara, mash_infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og);
+		} else {
+			dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og);
+		}
+		$('#est_fg').val(dataRecord.est_fg);
+		$('#est_fg2').val(dataRecord.est_fg);
+		$('#est_fg3').val(dataRecord.est_fg);
+
+		dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg);
+		$("#est_abv").val(dataRecord.est_abv);
+		$("#est_abv2").val(dataRecord.est_abv);
+
+		// Calculate the final svg if available use the real value.
+		if ((dataRecord.stage >= 6) && (dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
+			svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1);
+			console.log("real svg:"+svg);
+		}
+
 	};
 
 	/*
@@ -274,19 +312,6 @@
 		}
 	};
 
-	function calcFG() {
-		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(dataRecord.est_og, dataRecord.est_fg);
-		$("#est_abv").val(abv);
-		$("#est_abv2").val(abv);
-	};
-
 	function hopFlavourContribution(bt, vol, use, amount) {
 		var result;
 
@@ -341,27 +366,24 @@
 			hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size),
 					row.h_useat, parseFloat(row.h_amount));
 		}
-		total_ibus = Math.round(total_ibus);
-		ferm_ibus = Math.round(ferm_ibus);
+		total_ibus = Math.round(total_ibus * 10) / 10;
+		ferm_ibus = Math.round(ferm_ibus * 10) / 10;
+		hop_flavour = Math.round(hop_flavour * 100) / 10;
+		hop_aroma = Math.round(hop_aroma * 100) / 10;
+		if (hop_flavour > 100)
+			hop_flavour = 100;
+		if (hop_aroma > 100)
+			hop_aroma = 100;
 		console.log("calcIBUs(): " + total_ibus + "  flavour: " + hop_flavour + "  aroma: " + hop_aroma+"  fermenter:"+ferm_ibus);
 		dataRecord.est_ibu = total_ibus;
 		$('#est_ibu').val(total_ibus);
 		$('#est_ibu2').val(total_ibus);
-		$("#hop_flavour").jqxProgressBar('val', hop_flavour * 10);
-		$("#hop_aroma").jqxProgressBar('val', hop_aroma * 10);
+		$("#hop_flavour").jqxProgressBar('val', hop_flavour);
+		$("#hop_aroma").jqxProgressBar('val', hop_aroma);
 		$("#brew_fermenter_ibu").val(ferm_ibus);
 		calcStage();
 	};
 
-	function calcSVG() {
-		var rows = $('#yeastGrid').jqxGrid('getrows');
-		for (var i = 0; i < rows.length; i++) {
-			var row = rows[i];
-			if (row.y_use == 0)	// Primary
-				svg = parseFloat(row.y_attenuation);
-		}
-	}
-
 	function calcMashEfficiency() {
 //		console.log("calcMashEfficiency()");
 		var c = sg_to_plato(est_mash_sg);
@@ -1394,9 +1416,6 @@
 			dataRecord.batch_size = parseFloat(event.args.value);
 			calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal')));     // Keep the OG
 			calcFermentables();
-			calcSVG();
-			calcFG();
-			calcABV();
 			// TODO: adjust the hops, miscs, yeast, water.
 			calcIBUs();
 		});
@@ -1410,18 +1429,12 @@
 			$("#est_pre_vol").val(Math.round(new_boil * 1.04 * 100) / 100);
 			$("#boil_size").val(Math.round(new_boil * 100) / 100);
 			calcFermentables();
-			calcSVG();
-			calcFG();
-			calcABV();
 			// TODO: adjust the hops, miscs, yeast, water.
 			calcIBUs();
 		});
 		$('#efficiency').on('change', function (event) {
 			console.log("efficiency change:"+event.args.value);
 			calcFermentables();
-			calcSVG();
-			calcFG();
-			calcABV();
 			calcIBUs();
 		});
 		$('#est_og').on('change', function (event) {
@@ -1429,9 +1442,6 @@
 			$('#est_og2').val(event.args.value);
 			calcFermentablesFromOG(event.args.value);       // Adjust fermentables amounts
 			calcFermentables();                             // Update the recipe details
-			calcSVG();
-			calcFG();
-			calcABV();                                      // and ABV
 			calcIBUs();                                     // and the IBU's.
 		});
 		$('#mash_ph').on('change', function (event) {
@@ -1617,8 +1627,6 @@
 
 			calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal')));     // Keep the OG
 			calcFermentables();
-			calcSVG();
-			calcABV();
 			// TODO: adjust the hops, miscs, yeast, water.
 			calcIBUs();
 		}
@@ -1943,6 +1951,7 @@
 			$("#est_og3").val(0);
 			$("#est_fg").val(dataRecord.est_fg);
 			$("#est_fg2").val(dataRecord.est_fg);
+			$("#est_fg3").val(dataRecord.est_fg);
 			$("#est_color").val(dataRecord.est_color);
 			$("#est_color2").val(dataRecord.est_color);
 			$("#est_abv").val(dataRecord.est_abv);
@@ -2161,14 +2170,11 @@
                                                 $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100);
                                         }
                                         calcFermentables();
-                                        calcSVG();
-					calcFG();
-                                        calcABV();
                                         calcIBUs();
                                 });
                         },
                         ready: function() {
-                                calcFermentables();
+				calcFermentables();
                                 $('#jqxTabs').jqxTabs('next');
                         },
                         columns: [
@@ -2730,7 +2736,7 @@
                                 });
                         },
                         ready: function() {
-                                calcSVG();
+				calcFermentables();
                                 $('#jqxTabs').jqxTabs('next');
                         },
                         columns: [
@@ -2878,7 +2884,6 @@
                                 });
                         },
                         ready: function() {
-				calcFG();
                                 calcInit();
                                 $('#jqxLoader').jqxLoader('close');
                                 $('#jqxTabs').jqxTabs('first');
@@ -2998,7 +3003,7 @@
 	$("#st_og_max").jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'});
 	$("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
 
-	$("#est_fg").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' });
+	$("#est_fg").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
 	$("#est_fg").jqxNumberInput( Show3dec );
 	$("#st_fg_min").jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'});
 	$("#st_fg_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
@@ -3143,9 +3148,6 @@
 		$("#fermentableGrid").jqxGrid('sortby', 'f_amount', 'desc');
 		// Recalc percentages
 		calcFermentables();
-		calcSVG();
-		calcFG();
-		calcABV();
 		calcIBUs();
 		// Waters: yes there is impact.
 	});
@@ -3585,7 +3587,7 @@
 	});
 
 	// Tab 6, Yeasts
-	$("#est_fg2").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' });
+	$("#est_fg2").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
 	$("#est_fg2").jqxNumberInput( Show3dec );
 	$("#est_abv2").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' });
 	$("#est_abv2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true });
@@ -3602,9 +3604,7 @@
 	});
 	$("#YeastReady").jqxButton({ template: "success", width: '90px', theme: theme });
 	$("#YeastReady").click(function () {
-		calcSVG();
-		calcFG();
-		calcABV();
+		calcFermentables();
 		$("#yeastGrid").jqxGrid('sortby', 'y_use', 'asc');
 	});
 	$("#wy_name").jqxInput({ theme: theme, width: 320, height: 23 });
@@ -3656,9 +3656,7 @@
 			} else {
 				$("#wy_pmpt_amount").html("Volume ml:");
 			}
-			calcSVG();
-			calcFG();
-			calcABV();
+			calcFermentables();
 		}
 	});
 	$("#wy_amount").jqxNumberInput( Spin1dec );
@@ -3670,9 +3668,7 @@
 		else
 			var amount = parseFloat(event.args.value) / 1000;
 		rowdata.y_amount = amount;
-		calcSVG();
-		calcFG();
-		calcABV();
+		calcFermentables();
 	});
 	$("#wy_use").jqxDropDownList({
 		theme: theme,
@@ -3689,9 +3685,7 @@
 			var index = event.args.index;
 			var rowdata = $("#yeastGrid").jqxGrid('getrowdata', yeastRow);
 			rowdata.y_use = index;
-			calcSVG();
-			calcFG();
-			calcABV();
+			calcFermentables();
 		}
 	});
 
@@ -4098,6 +4092,7 @@
 	$("#brew_aboil_efficiency").jqxNumberInput( Show1dec );
 	$("#brew_sparge_temperature").jqxNumberInput( Spin1dec );
 	$("#brew_sparge_volume").jqxNumberInput( Spin1dec );
+	$("#brew_sparge_est").jqxNumberInput( Show1dec );
 	$("#brew_whirlpool9").jqxNumberInput( PosInt );
 	$("#brew_whirlpool9").jqxNumberInput({ max: 120 });
 	$("#brew_cooling_to").jqxNumberInput( Spin1dec );
@@ -4162,6 +4157,8 @@
 	$('#secondary_end_date').on('close', function (event) { calcStage(); });
 	$("#tertiary_temp").jqxNumberInput( YeastT );
 	$("#fg").jqxNumberInput( Spin3dec );
+	$("#est_fg3").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
+	$("#est_fg3").jqxNumberInput( Show3dec );
 	$("#final_abv").jqxNumberInput( Show1dec );
 	$("#final_svg").jqxNumberInput( Show1dec );
 	$("#FLog").jqxButton({ template: "info", width: '150px', theme: theme });
--- a/www/prod_edit.php	Sat Feb 09 22:12:31 2019 +0100
+++ b/www/prod_edit.php	Sun Feb 10 16:14:48 2019 +0100
@@ -466,70 +466,69 @@
        <td><div id="brew_aboil_efficiency"></div></td>
       </tr>
       <tr>
+       <td colspan="6">&nbsp;</td>
+      </tr>
+      <tr>
        <th style="text-align: center;" colspan="2">Spoelen en filteren</th>
-       <td colspan="4"> </td>
+       <th style="text-align: center;" colspan="4">Koelen en whirlpoolen</th>
       </tr>
       <tr>
        <td style="vertical-align: top; float: right;">Spoelwater &deg;C:</td>
        <td><div id="brew_sparge_temperature"></div></td>
-       <th style="text-align: center;" colspan="4">Koelen en whirlpoolen</th>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater liters:</td>
-       <td><div id="brew_sparge_volume"></div></td>
        <td style="vertical-align: top; float: right;">Whirlpool 85..100&deg;C min:</td>
        <td><div id="brew_whirlpool9"></div></td>
        <td style="vertical-align: top; float: right;">Koelen tot &deg;C:</td>
        <td><div id="brew_cooling_to"></div></td>
       </tr>
       <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater pH:</td>
-       <td><div id="brew_sparge_ph"></div></td>
+       <td style="vertical-align: top; float: right;">Spoelwater voorraad l:</td>
+       <td><div id="brew_sparge_volume"></div></td>
        <td style="vertical-align: top; float: right;">Whirlpool 72..79&deg;C min:</td>
        <td><div id="brew_whirlpool7"></div></td>
        <td style="vertical-align: top; float: right;">Koelen met:</td>
        <td><div id="brew_cooling_method"></div></td>
       </tr>
       <tr>
-       <td colspan="2"></td>
+       <td style="vertical-align: top; float: right;">Spoelwater nodig l:</td>
+       <td><div id="brew_sparge_est"></div></td>
        <td style="vertical-align: top; float: right;">Whirlpool 60..66&deg;C min:</td>
        <td><div id="brew_whirlpool6"></div></td>
        <td style="vertical-align: top; float: right;">Koelen minuten:</td>
        <td><div id="brew_cooling_time"></div></td>
       </tr>
       <tr>
-       <th style="text-align: center;" colspan="2">Beluchten</th>
+       <td style="vertical-align: top; float: right;">Spoelwater pH:</td>
+       <td><div id="brew_sparge_ph"></div></td>
        <td style="vertical-align: top; float: right;">Whirlpool koud min:</td>
        <td><div id="brew_whirlpool2"></div></td>
        <td colspan="2"> </td>
       </tr>
       <tr>
-       <td style="vertical-align: top; float: right;">Beluchten met:</td>
-       <td><div id="brew_aeration_type"></div></td>
-       <td colspan="4"> </td>
+       <td colspan="6">&nbsp;</td>
       </tr>
       <tr>
-       <td style="vertical-align: top; float: right;">Beluchten tijd min:</td>
-       <td><div id="brew_aeration_time"></div></td>
+       <th style="text-align: center;" colspan="2">Beluchten</th>
        <th style="text-align: center;" colspan="4">Naar gistvat</th>
       </tr>
       <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;">Beluchten met:</td>
+       <td><div id="brew_aeration_type"></div></td>
        <td style="vertical-align: top; float: right;">Koeler en trub verlies l:</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;">Beluchten tijd min:</td>
+       <td><div id="brew_aeration_time"></div></td>
        <td style="vertical-align: top; float: right;">Extra water in gistvat l:</td>
        <td><div id="brew_fermenter_extrawater"></div></td>
        <td style="vertical-align: top; float: right;">Kleur in gistvat EBC:</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;">Beluchten snelheid:</td>
+       <td><div id="brew_aeration_speed"></div></td>
        <td style="vertical-align: top; float: right;">Volume naar gistvat l:</td>
        <td><div id="brew_fermenter_volume"></div></td>
        <td style="vertical-align: top; float: right;">Bitterheid in gistvat IBU:</td>
@@ -607,15 +606,15 @@
         <th style="text-align: center;" colspan="4">&nbsp;</th>
        </tr>
        <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG:</td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Het behaalde eind SG:</td>
 	<td align="left" style="vertical-align: top;"><div id="fg"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Voorspeld:</td>
-        <td align="left" style="vertical-align: top;"><div id="est_fg2"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Het verwachte eind SG:</td>
+        <td align="left" style="vertical-align: top;"><div id="est_fg3"></div></td>
        </tr>
        <tr>
         <td style="vertical-align: top; float: right; padding: 3px;">Alcohol percentage voor hergisting:</td>
         <td align="left" style="vertical-align: top;"><div id="final_abv"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad %:</td>
         <td align="left" style="vertical-align: top;"><div id="final_svg"></div></td>
        </tr>
       </table>

mercurial