ABV calculation uses Daniels method. sg_to_plato and plato_to_sg functions use brewersfriend calculation. Added sg_to_brix and brix_to_sg functions. Make brewdate tab read only when the primary fermentation is ready. Brix aid input functions for primary end sg and final sg fields. Added tooltips on the fermentation tab. Changes in the layout of the fermentation tab.

Sat, 23 Feb 2019 19:55:42 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 23 Feb 2019 19:55:42 +0100
changeset 282
f765249d57d7
parent 281
fef03c7ae353
child 283
879b81864e4e

ABV calculation uses Daniels method. sg_to_plato and plato_to_sg functions use brewersfriend calculation. Added sg_to_brix and brix_to_sg functions. Make brewdate tab read only when the primary fermentation is ready. Brix aid input functions for primary end sg and final sg fields. Added tooltips on the fermentation tab. Changes in the layout of the fermentation 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	Thu Feb 21 16:36:02 2019 +0100
+++ b/www/js/global.js	Sat Feb 23 19:55:42 2019 +0100
@@ -117,6 +117,7 @@
 	{ id: 0, en: 'Pellet', nl: 'pellets' },
 	{ id: 1, en: 'Plug',   nl: 'plugs' },
 	{ id: 2, en: 'Leaf',   nl: 'bellen' }
+//	{ id: 3, en: 'Leaf wet', nl: 'bellen nat' }
 ];
 var HopFormSource = {
 	localdata: HopFormData,
@@ -786,6 +787,11 @@
  */
 function abvol(og, fg) {
 
+	if ((og - fg) < 0)
+		return 0;
+
+	return (76.08 * (og-fg) / (1.775-og)) * (fg / 0.794); // Daniels
+// brouwhulp
 	if ((4.749804 - fg) != 0)
 		return 486.8693 * (og - fg) / (4.749804 - fg);
 	return 0;
@@ -842,6 +848,9 @@
 	if (Form == 1 ) {	// Plug
 		pfactor += my_factor_plug / 100;
 	}
+//	if (Form == 3) {	// Wet leaf
+//		pfactor += 5.5;	// From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py
+//	}
 
 	if (Method == 0) {	// Tinseth
 		/* http://realbeer.com/hops/research.html */
@@ -958,17 +967,26 @@
 
 
 function sg_to_plato(sg) {
-	if (sg > 0.5)
-		return 259 - 259 / sg;
-	return 0;
+	// http://www.brewersfriend.com/2012/10/31/on-the-relationship-between-plato-and-specific-gravity/
+	return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868;
 }
 
 
 
 function plato_to_sg(plato) {
-	if (plato < 259)
-		return 259 / (259 - plato);
-	return 1.000;
+	return 1 + (plato / (258.6 - ((plato / 258.2) * 227.1)));
+}
+
+
+
+function brix_to_sg(brix) {
+	return plato_to_sg(brix / my_brix_correction);
+}
+
+
+
+function sg_to_brix(sg) {
+	return sg_to_plato(sg) * my_brix_correction;
 }
 
 
@@ -1035,4 +1053,3 @@
 	return f2d + 2*f3d + 3*f4d;
 }
 
-
--- a/www/js/prod_edit.js	Thu Feb 21 16:36:02 2019 +0100
+++ b/www/js/prod_edit.js	Sat Feb 23 19:55:42 2019 +0100
@@ -1628,6 +1628,8 @@
 	function calcFermentation() {
 		if (dataRecord.brew_fermenter_sg < 1.020)
 			return;
+		var obrix = sg_to_brix(dataRecord.brew_fermenter_sg);
+		console.log("calcFermentation() og:"+dataRecord.brew_fermenter_sg+" brix:"+obrix);
 		if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) {
 			var primary_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.primary_end_sg) / (dataRecord.brew_fermenter_sg - 1);
 			//console.log("primary svg: "+primary_svg);
@@ -1807,6 +1809,33 @@
 			$("#sparge_acid_type").jqxDropDownList({ disabled: true });
 			$("#sparge_acid_perc").jqxNumberInput({ spinButtons: false, readOnly: true, width: false });
 		}
+		if (dataRecord.stage > 3) { // Primary fermentation done
+			$("#brew_date_start").jqxDateTimeInput({ disabled: true });
+			$("#brew_date_end").jqxDateTimeInput({ disabled: true });
+			$("#brew_mash_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_preboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_mash_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_preboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_preboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_sparge_temperature").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_whirlpool9").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_cooling_to").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_sparge_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_whirlpool7").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_cooling_method").jqxDropDownList({ disabled: true });
+			$("#brew_whirlpool6").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_cooling_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_sparge_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_whirlpool2").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aeration_type").jqxDropDownList({ disabled: true });
+			$("#brew_fermenter_tcloss").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aeration_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_fermenter_extrawater").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+			$("#brew_aeration_speed").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 });
+		}
 		if (dataRecord.stage < 5) { // At least secondary
 			$('#jqxTabs').jqxTabs('disableAt', 10);	// Packaging tab
 		} else {
@@ -2168,7 +2197,45 @@
 			dataRecord.primary_end_sg = parseFloat(event.args.value);
 			calcFermentation();
 		});
-
+		$("#primary_end_brix").on('change', function (event) {
+			// Brix reading from refractometer RI
+			if (dataRecord.brew_fermenter_sg >= 1.020) {
+				OBrix = sg_to_brix(dataRecord.brew_fermenter_sg);
+				FBrix = parseFloat(event.args.value) / my_brix_correction;
+				// http://seanterrill.com/2011/04/07/refractometer-fg-results/
+				var FG = 1.0000 - 0.0044993 * OBrix + 0.0117741 * FBrix +
+					 0.000275806 * (OBrix * OBrix) - 0.00127169 * (FBrix * FBrix) -
+					 0.00000727999 * Math.pow(OBrix, 3) + 0.0000632929 * Math.pow(FBrix, 3);
+	//			var FG = 1.0000 - 0.00085683 * OBrix + 0.0034941 * FBrix;
+				// Brouwhulp
+	//			var FG = ((1.001843 - 0.002318474 * OBrix - 0.000007775 * (OBrix * OBrix)
+	//				  - 0.000000034 * Math.pow(OBrix, 3) + 0.00574 * (FBrix)
+	//				  + 0.00003344 * (FBrix * FBrix) + 0.000000086 * Math.pow(FBrix, 3))
+	//				  + (1.313454) * 0.001);
+				console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG);
+				if (FG > 1.00001) {
+					$("#primary_end_sg").val(FG);
+					dataRecord.primary_end_sg = FG;
+				}
+				calcFermentation();
+			}
+		});
+		$("#final_brix").on('change', function (event) {
+			// Brix reading from refractometer RI
+			if (dataRecord.brew_fermenter_sg >= 1.020) {
+				OBrix = sg_to_brix(dataRecord.brew_fermenter_sg);
+				FBrix = parseFloat(event.args.value) / my_brix_correction;
+				var FG = 1.0000 - 0.0044993 * OBrix + 0.0117741 * FBrix +
+					 0.000275806 * (OBrix * OBrix) - 0.00127169 * (FBrix * FBrix) -
+					 0.00000727999 * Math.pow(OBrix, 3) + 0.0000632929 * Math.pow(FBrix, 3);
+				console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG);
+				if (FG > 1.00001) {
+					$("#fg").val(FG);
+					dataRecord.fg = FG;
+				}
+				calcFermentation();
+			}
+		});
 		$("#BLog").jqxButton({ disabled: (dataRecord.log_brew) ? false:true });
 		$("#FLog").jqxButton({ disabled: (dataRecord.log_fermentation) ? false:true });
 	};
@@ -5105,11 +5172,19 @@
 
 	// Tab 10, Fermentation
 	// Note, fermentation temps changes must do calcCarbonation()
+	$("#brew_fermenter_sg2").jqxTooltip({ content: 'Het behaalde SG in het gistvat, overgenomen van de brouwdag.' });
 	$("#brew_fermenter_sg2").jqxNumberInput( Show3dec );
+	$("#primary_start_temp").jqxTooltip({ content: 'De begintemperatuur van de hoofdvergisting.' });
 	$("#primary_start_temp").jqxNumberInput( YeastT );
+	$("#primary_max_temp").jqxTooltip({ content: 'De hoogst bereikte piek temperatuur tijdens de hoofgvergisting.' });
 	$("#primary_max_temp").jqxNumberInput( YeastT );
+	$("#primary_end_temp").jqxTooltip({ content: 'De eind temperatuur van de hoofdvergisting.' });
 	$("#primary_end_temp").jqxNumberInput( YeastT );
+	$("#primary_end_sg").jqxTooltip({ content: 'Het gemeten SG aan het eind van de hoofdvergisting.' });
 	$("#primary_end_sg").jqxNumberInput( SGopts );
+	$("#primary_end_brix").jqxTooltip({ content: 'Hulpfinctie: de afgelezen &deg;Brix RI waarde met een refractometer.' });
+	$("#primary_end_brix").jqxNumberInput( Spin1dec );
+	$("#primary_svg").jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de hoofdgisting.' });
 	$("#primary_svg").jqxNumberInput( Show1dec );
 	$("#primary_end_date").jqxTooltip({ content: 'De eind datum van de hoofdvergisting en eventueel overhevelen.' });
 	$("#primary_end_date").jqxDateTimeInput( Dateopts );
@@ -5122,6 +5197,8 @@
 	$("#fg").jqxNumberInput( Spin3dec );
 	$("#est_fg3").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
 	$("#est_fg3").jqxNumberInput( Show3dec );
+	$("#final_brix").jqxTooltip({ content: 'Hulpfinctie: de afgelezen &deg;Brix RI waarde met een refractometer.' });
+	$("#final_brix").jqxNumberInput( Spin1dec );
 	$("#final_abv").jqxNumberInput( Show1dec );
 	$("#final_svg").jqxNumberInput( Show1dec );
 	$("#FLog").jqxButton({ template: "info", width: '150px', theme: theme });
--- a/www/prod_edit.php	Thu Feb 21 16:36:02 2019 +0100
+++ b/www/prod_edit.php	Sat Feb 23 19:55:42 2019 +0100
@@ -630,15 +630,15 @@
         <th style="text-align: center;" colspan="4">Hoofdvergisting</th>
        </tr>
        <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">OG begin vergisting:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="brew_fermenter_sg2"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Begin vergisting SG:</td>
+	<td align="left" colspan="3" style="vertical-align: top;"><div id="brew_fermenter_sg2"></div></td>
        </tr>
        <tr>
         <td style="vertical-align: top; float: right; padding: 3px;">Start temperatuur hoofdvergisting &deg;C:</td>
         <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_start_temp"></div></td>
        </tr>
        <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Maximum temperatuur hoofdvergisting &deg;C:</td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Piek temperatuur hoofdvergisting &deg;C:</td>
         <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_max_temp"></div></td>
        </tr>
        <tr>
@@ -646,14 +646,16 @@
         <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_temp"></div></td>
        </tr>
        <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG hoofdvergisting:</td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting SG:</td>
 	<td align="left" style="vertical-align: top;"><div id="primary_end_sg"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
-        <td align="left" style="vertical-align: top;"><div id="primary_svg"></div></td>
+	<td style="vertical-align: top; float: right; padding: 3px;">Afgelezen &deg;Brix RI:</td>
+        <td align="left" style="vertical-align: top;"><div id="primary_end_brix"></div></td>
        </tr>
        <tr>
         <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting/overhevelen:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_date"></div></td>
+	<td align="left" style="vertical-align: top;"><div id="primary_end_date"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
+        <td align="left" style="vertical-align: top;"><div id="primary_svg"></div></td>
        </tr>
        <tr>
         <td colspan="4"><hr></td>
@@ -683,10 +685,14 @@
         <th style="text-align: center;" colspan="4">&nbsp;</th>
        </tr>
        <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Het verwachte eind SG:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="est_fg3"></div></td>
+       </tr>
+       <tr>
         <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;">Het verwachte eind SG:</td>
-        <td align="left" style="vertical-align: top;"><div id="est_fg3"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Afgelezen &deg;Brix RI:</td>
+        <td align="left" style="vertical-align: top;"><div id="final_brix"></div></td>
        </tr>
        <tr>
         <td style="vertical-align: top; float: right; padding: 3px;">Alcohol percentage voor hergisting:</td>

mercurial