# HG changeset patch # User Michiel Broek # Date 1557346940 -7200 # Node ID c314277905e69b3c927b9ca86e30ccef63998483 # Parent 0e44535f74351261b131e5c7b7a902fb64abc40f Added mash thickness calculation. Backported some water calculations from the product editor. diff -r 0e44535f7435 -r c314277905e6 www/includes/db_recipes.php --- 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 .= ']'; diff -r 0e44535f7435 -r c314277905e6 www/js/rec_edit.js --- 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(""+rangeCode + ""); - else if (rangeCode == "hoog") - $("#wr_"+ion).html(""+rangeCode+""); else $("#wr_"+ion).html(""); } @@ -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) {