Added mash thickness calculation. Backported some water calculations from the product editor. stable

Wed, 08 May 2019 22:22:20 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 08 May 2019 22:22:20 +0200
branch
stable
changeset 350
c314277905e6
parent 349
0e44535f7435
child 351
58c350f286e5
child 353
c40d3c276f32

Added mash thickness calculation. Backported some water calculations from the product editor.

www/includes/db_recipes.php file | annotate | diff | comparison | revisions
www/js/rec_edit.js file | annotate | diff | comparison | revisions
--- a/www/includes/db_recipes.php	Tue Apr 30 16:12:09 2019 +0200
+++ b/www/includes/db_recipes.php	Wed May 08 22:22:20 2019 +0200
@@ -244,9 +244,9 @@
 				$mash .= ',"step_infuse_amount":0';
 			$mash .= ',"step_temp":' . $item['step_temp'];
 			$mash .= ',"step_time":' . $item['step_time'];
+			$mash .= ',"step_thickness":' . $item['step_thickness'];
 			$mash .= ',"ramp_time":' . $item['ramp_time'];
 			$mash .= ',"end_temp":' . $item['end_temp'] . '}';
-			//syslog(LOG_NOTICE, $mash);
 			$mashs .= $mash;
 		}
 	}
@@ -297,6 +297,7 @@
 	$recipes = '[';
 	$comma = FALSE;
 	while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
+		$mashkg = 0;
 		// Manual encode to JSON.
 		if ($comma) {
 			$recipes .= ',';
@@ -375,6 +376,9 @@
 			// Append stock information.
 			$fermentables = json_decode($row['json_fermentables'], true);
 			for ($i = 0; $i < count($fermentables); $i++) {
+				if ($fermentables[$i]['f_added'] == 0) {
+					$mashkg += $fermentables[$i]['f_amount'];
+				}
 				$fermentables[$i]['f_inventory'] = 0;	// Not in stock
 				$fermentables[$i]['f_avail'] = 0;	// Ingredient not in db
 				$sql2 = "SELECT inventory FROM inventory_fermentables ";
@@ -453,7 +457,20 @@
 			$recipes .= ',"miscs":' . $row['json_miscs'];
 			$recipes .= ',"yeasts":' . $row['json_yeasts'];
 		}
-		$recipes .= ',"mashs":' . $row['json_mashs'];
+		if (isset($_GET['record'])) {
+			$volume = 0;
+			$mashs = json_decode($row['json_mashs'], true);
+                        for ($i = 0; $i < count($mashs); $i++) {
+				$volume += $mashs[$i]['step_infuse_amount'];
+				if ($mashkg > 0)
+					$mashs[$i]['step_thickness'] = floatval(sprintf("%.3f", $volume / $mashkg));
+				else
+					$mashs[$i]['step_thickness'] = 0;
+			}
+			$recipes .= ',"mashs":' . json_encode($mashs, JSON_UNESCAPED_UNICODE);
+		} else {
+			$recipes .= ',"mashs":' . $row['json_mashs'];
+		}
 		$recipes .= '}';
 	}
 	$recipes .= ']';
--- a/www/js/rec_edit.js	Tue Apr 30 16:12:09 2019 +0200
+++ b/www/js/rec_edit.js	Wed May 08 22:22:20 2019 +0200
@@ -46,8 +46,6 @@
 
 	var	to_100 = false;		// Fermentables adjust to 100%
 	var	preboil_sg = 0;
-//	var	sugarsm = 0;		// Sugars after mash
-//	var	sugarsf = 0;		// Sugars after boil
 	var     psugar = 0;     	// Percentage real sugars
 	var     pcara = 0;      	// Percentage cara/crystal malts
 	var	svg = 77;		// Default attenuation
@@ -440,39 +438,6 @@
 		$('#wg_amount').val(mash_infuse);
 	};
 
-/*	function GetBUGUMin() {
-
-		var Result = 0;
-
-		if (((dataRecord.st_og_max + dataRecord.st_og_min) > 0) && ((dataRecord.st_ibu_max + dataRecord.st_ibu_min) > 0)) {
-			var G = (dataRecord.st_og_max - dataRecord.st_og_min) / ((dataRecord.st_og_max + dataRecord.st_og_min) / 2);
-			var B = (dataRecord.st_ibu_max - dataRecord.st_ibu_min) / ((dataRecord.st_ibu_max + dataRecord.st_ibu_min) / 2);
-			if (G > B)
-				Result = ((dataRecord.st_ibu_max + dataRecord.st_ibu_min) / 2) / (1000 * (dataRecord.st_og_max - 1));
-			else
-				Result = dataRecord.st_ibu_min / (1000 * (((dataRecord.st_og_max + dataRecord.st_og_min) / 2) - 1));
-		}
-		console.log("GetBUGUMin(): "+Result);
-		return Result;
-	}
-
-	function GetBUGUMax() {
-
-		var Result = 0;
-
-		if (((dataRecord.st_og_max + dataRecord.st_og_min) > 0) && ((dataRecord.st_ibu_max + dataRecord.st_ibu_min) > 0) && (dataRecord.st_og_min > 0)) {
-			var G = (dataRecord.st_og_max - dataRecord.st_og_min) / ((dataRecord.st_og_max + dataRecord.st_og_min) / 2);
-			var B = (dataRecord.st_ibu_max - dataRecord.st_ibu_min) / ((dataRecord.st_ibu_max + dataRecord.st_ibu_min) / 2);
-			if (G > B)
-				Result = ((dataRecord.st_ibu_min + dataRecord.st_ibu_max) / 2) / (1000 * (dataRecord.st_og_min - 1));
-			else
-				Result = dataRecord.st_ibu_max / (1000 * (((dataRecord.st_og_max + dataRecord.st_og_min) / 2) - 1));
-
-		}
-		console.log("GetBUGUMax(): "+Result);
-		return Result;
-	} */
-
 	function GetBUGU() {
 		var gu = (dataRecord.est_og - 1) * 1000;
 		if (gu > 0)
@@ -487,7 +452,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++) {
@@ -536,10 +501,8 @@
 	}
 
 	function setRangeIndicator(ion, rangeCode) {
-		if (rangeCode == "laag")
+		if ((rangeCode == "laag") || (rangeCode == "hoog"))
 			$("#wr_"+ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>"+rangeCode + "</span>");
-		else if (rangeCode == "hoog")
-			$("#wr_"+ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>"+rangeCode+"</span>");
 		else
 			$("#wr_"+ion).html("<img src='images/dialog-ok-apply.png'>");
 	}
@@ -622,11 +585,9 @@
 					}
 				}
 				x = C1 * (pHZ - row.f_di_ph);	// AcidRequired(ZpH)
-	//			console.log(row.f_name+" C1: "+C1+" ZpH: "+pHZ+" di_ph: "+row.f_di_ph+" acid rquired: "+x);
 				Result += x * row.f_amount;
 			}
 		}
-	//	console.log("Final: "+Result);
 		return Result;
 	}
 
@@ -651,7 +612,7 @@
 	function GetAcidSpecs(AT) {
 		switch(AT) {
 			case 0:	return {	// Melkzuur
-					pK1: 3.08,
+					pK1: 3.86,
 					pK2: 20,
 					pK3: 20,
 					MolWt: 90.08,
@@ -659,7 +620,7 @@
 					AcidPrc: 0.88
 				};
 			case 1:	return {	// Zoutzuur
-					pK1: -10,
+					pK1: -7,
 					pK2: 20,
 					pK3: 20,
 					MolWt: 36.46,
@@ -675,7 +636,7 @@
 					AcidPrc: 0.25
 				};
 			case 3:	return {	// Zwavelzuur
-					pK1: -10,
+					pK1: -1,
 					pK2: 1.92,
 					pK3: 20,
 					MolWt: 98.07,
@@ -791,8 +752,8 @@
 		if (last_base == '')
 			last_base = BaseTypeData[$("#wa_base_name").val()].nl;
 
-		var AT = dataRecord.wa_acid_name; // parseFloat($("#wa_acid_name").jqxNumberInput('decimal'));
-		var BT = dataRecord.wa_base_name; //parseFloat($("#wa_base_name").jqxNumberInput('decimal'));
+		var AT = dataRecord.wa_acid_name;
+		var BT = dataRecord.wa_base_name;
 
 		var result = GetAcidSpecs(AT);
 		var pK1 = result.pK1;
@@ -978,8 +939,6 @@
 				var deltapd = 0.1;
 				var pd = ProtonDeficit(pHa);
 				var n = 0;
-		//		console.log("n: "+n+" pd: "+pd+" protonDeficit: "+protonDeficit+" frac: "+frac+" pHa: "+pHa);
-
 				while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) {
 					n++;
 					if (pd < (protonDeficit-deltapd))
@@ -1122,11 +1081,11 @@
 			}
 		}
 
-		console.log("calcSparge() target pH: "+TargetpH+" Source: "+Source_pH+" alkalinity: "+Source_alkalinity);
+		//console.log("calcSparge() target pH: "+TargetpH+" Source: "+Source_pH+" alkalinity: "+Source_alkalinity);
 
 		// Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH
 		var r1 = Math.pow(10, Source_pH - 6.38);
-		var r2 = Math.pow(10, Source_pH - 10.33);
+		var r2 = Math.pow(10, Source_pH - 10.373);
 		var d = 1 + r1 + r1*r2;
 		var f1 = 1/d;
 		var f2 = r1/d;
@@ -1134,7 +1093,7 @@
 
 		//Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity)
 		var r143 = Math.pow(10, 4.3 - 6.38);
-		var r243 = Math.pow(10, 4.3 - 10.33);
+		var r243 = Math.pow(10, 4.3 - 10.373);
 		var d43 = 1 + r143 + r143*r243;
 		var f143 = 1/d43;
 		var f243 = r143 / d43;
@@ -1143,22 +1102,25 @@
 		//Step 3. Convert the sample alkalinity to milliequivalents/L
 		var alkalinity = Source_alkalinity / 50;
 		//Step 4. Solve
-		alkalinity = alkalinity / ((f143-f1)+(f3-f343));
+		var Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143-f1)+(f3-f343));
 
 		//Step 5. Compute mole fractions at desired pH
 		var r1g = Math.pow(10, TargetpH - 6.38);
-		var r2g = Math.pow(10, TargetpH - 10.33);
+		var r2g = Math.pow(10, TargetpH - 10.373);
 		var dg = 1 + r1g + r1g*r2g;
 		var f1g = 1/dg;
 		var f2g = r1g / dg;
 		var f3g = r1g * r2g / dg;
 
 		//Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L)
-		var Acid = alkalinity * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH);  //mEq/l
+		var Acid = Ct * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH);  //mEq/l
+                Acid += 0.01;   // Add acid that would be required for distilled water.
 		if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) {
 			dataRecord.sparge_acid_type = 0;
 			$("#sparge_acid_type").val(0);
 		}
+
+		//Step 8. Get the acid data.
 		var AT = dataRecord.sparge_acid_type;
 		var result = GetAcidSpecs(AT);
 		var pK1 = result.pK1;
@@ -1176,7 +1138,7 @@
 		Acid *= MolWt; //mg
 
 		Acid = Acid / AcidSG; //ml ; 88% lactic solution
-		f1 = dataRecord.sparge_acid_perc;
+		var f1 = dataRecord.sparge_acid_perc;
 		if (f1 <= 0.1)
 			f1 = AcidPrc;
 		Acid = Acid * AcidPrc / (f1 / 100);
@@ -2566,6 +2528,7 @@
 			row["step_infuse_amount"] = 15;
 			row["step_temp"] = 62.0;
 			row['step_time'] = 20.0;
+			row['step_thickness'] = 0;
 			row['ramp_time'] = 1.0;
 			row['end_temp'] = 62.0;
 			return row;
@@ -2581,6 +2544,7 @@
 				{ name: 'step_infuse_amount', type: 'float' },
 				{ name: 'step_temp', type: 'float' },
 				{ name: 'step_time', type: 'float' },
+				{ name: 'step_thickness', type: 'float' },
 				{ name: 'ramp_time', type: 'float' },
 				{ name: 'end_temp', type: 'float' }
                         ],
@@ -2636,7 +2600,6 @@
 				calcInit();
 				$('#jqxLoader').jqxLoader('close');
 				$('#jqxTabs').jqxTabs('first');
-		//		setReadonly(dataRecord.locked);
 			},
                         columns: [
 				{ text: 'Stap naam', datafield: 'step_name' },
@@ -2650,6 +2613,7 @@
 				{ text: 'Rust min.', datafield: 'step_time', width: 90, align: 'right', cellsalign: 'right' },
 				{ text: 'Stap min.', datafield: 'ramp_time', width: 90, align: 'right', cellsalign: 'right' },
 				{ text: 'Infuse L.', datafield: 'step_infuse_amount', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' },
+				{ text: 'L/Kg.', datafield: 'step_thickness', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f2' },
 				{ text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () {
 					return "Wijzig";
 					}, buttonclick: function (row) {
@@ -3421,6 +3385,10 @@
 				else
 					row["step_infuse_amount"] = 0;
 				row["step_temp"] = data.step_temp;
+				if (mashkg > 0)
+					row["step_thickness"] = parseFloat(mash_infuse / mashkg);
+				else
+					row["step_thickness"] = 0;
 				row["end_temp"] = data.end_temp;
 				row["step_time"] = data.step_time;
 				row["ramp_time"] = data.ramp_time;
@@ -3442,6 +3410,18 @@
 	$("#MashReady").jqxButton({ template: "success", width: '90px', theme: theme });
 	$("#MashReady").click(function () {
 		$("#mashGrid").jqxGrid('sortby', 'step_temp', 'asc');
+		mash_infuse = 0;
+                var rows = $('#mashGrid').jqxGrid('getrows');
+                for (var i = 0; i < rows.length; i++) {
+                	var row = rows[i];
+                	if (row.step_type == 0) // Infusion
+                		mash_infuse += parseFloat(row.step_infuse_amount);
+			var rowdata = $("#mashGrid").jqxGrid('getrowdata', i);
+			if (mashkg > 0)
+				rowdata.step_thickness = parseFloat(mash_infuse / mashkg);
+			else
+				rowdata.step_thickness = 0;
+                }
 	});
 	$("#wstep_name").jqxInput({ theme: theme, width: 320, height: 23 });
 	$("#wstep_name").on('change', function (event) {

mercurial