# HG changeset patch # User Michiel Broek # Date 1572204009 -3600 # Node ID 41d21817608ef7382c1674523a79fe6df7e67ba3 # Parent 7c37a6f85d55cf501741d6749a94d91347b7d4f3 Added the IBU contribution for whirlpool hops. diff -r 7c37a6f85d55 -r 41d21817608e www/js/global.js --- a/www/js/global.js Mon Oct 21 14:38:48 2019 +0200 +++ b/www/js/global.js Sun Oct 27 20:20:09 2019 +0100 @@ -872,7 +872,7 @@ /* * Berekeningen uit https://www.hobbybrouwen.nl/forum/index.php/topic,6079.msg69464.html#msg69464 */ -function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method) { +function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method, Whirlpool9, Whirlpool7, Whirlpool6) { var gravity, liters, alpha, mass, time, fmoment = 1.0, pfactor = 1.0, ibu = 0, boilfactor, sgfactor, AddedAlphaAcids, Bigness_factor, BoilTime_factor, utiisation; @@ -901,13 +901,33 @@ pfactor += my_factor_cryohop / 100; } + // Ideas from Zymurgy March-April 2018. These are not exact formulas! + whirlibus = 0; + if (Use == 4) { // Any whirlpool + if (Whirlpool9) { + // 20 mg/l/50 min + whirlibus += (alpha * mass * 20) / liters * (Whirlpool9 / 50); + console.log('Whirlpool9:' + alpha * mass * 20 + ' liter:' + liters + ' time:' + Whirlpool9 + ' ibu' + (alpha * mass * 20) / liters * (Whirlpool9 / 50)); + } + if (Whirlpool7) { + // 6 mg/l/50 min + whirlibus += (alpha * mass * 6) / liters * (Whirlpool7 / 50); + console.log('Whirlpool7:' + alpha * mass * 6 + ' liter:' + liters + ' time:' + Whirlpool7 + ' ibu' + (alpha * mass * 6) / liters * (Whirlpool7 / 50)); + } + if (Whirlpool6) { + // 2 mg/l/50 min + whirlibus += (alpha * mass * 2) / liters * (Whirlpool6 / 50); + console.log('Whirlpool6:' + alpha * mass * 2 + ' liter:' + liters + ' time:' + Whirlpool6 + ' ibu' + (alpha * mass * 2) / liters * (Whirlpool6 / 50)); + } + } + if (Method == 0) { // Tinseth /* http://realbeer.com/hops/research.html */ AddedAlphaAcids = (alpha * mass * 1000) / liters; Bigness_factor = 1.65 * Math.pow(0.000125, gravity - 1); BoilTime_factor = ((1 - Math.exp(-0.04 * time)) / 4.15); utiisation = Bigness_factor * BoilTime_factor; - ibu = Round(utiisation * AddedAlphaAcids * fmoment * pfactor, 1); + ibu = Round(utiisation * AddedAlphaAcids * fmoment * pfactor + whirlibus, 1); } if (Method == 2) { // Daniels if (Form == 2) // Leaf @@ -918,7 +938,7 @@ sgfactor = 0; else sgfactor = (gravity - 1050) / 200; - ibu = Round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))), 1); + ibu = Round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) + whirlibus, 1); } if (Method == 1) { // Rager boilfactor = fmoment * 18.11 + 13.86 * Math.tanh((time * 31.32) / 18.27); @@ -926,10 +946,11 @@ sgfactor = 0; else sgfactor = (gravity - 1050) / 200; - ibu = Round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)), 1); + ibu = Round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) + whirlibus, 1); } - //console.log("toIBU("+Use+","+Form+","+SG+","+Volume+","+Amount+","+Boiltime+","+Alpha+","+Method+"):"+ibu+" fm:"+fmoment+" pf:"+pfactor); +// console.log('toIBU(' + Use + ',' + Form + ',' + SG + ',' + Volume + ',' + Amount + ',' + Boiltime + ',' + +// Alpha + ',' + Method + ',' + Whirlpool9 + ',' + Whirlpool7 + ',' + Whirlpool6 + '):' + ibu + ' fm:' + fmoment + ' pf:' + pfactor); return ibu; } diff -r 7c37a6f85d55 -r 41d21817608e www/js/prod_edit.js --- a/www/js/prod_edit.js Mon Oct 21 14:38:48 2019 +0200 +++ b/www/js/prod_edit.js Sun Oct 27 20:20:09 2019 +0100 @@ -810,7 +810,7 @@ { name: 'h_type', type: 'int' }, { name: 'h_form', type: 'int' }, { name: 'h_useat', type: 'int' }, - { name: 'h_time', type: 'float' }, + { name: 'h_time', type: 'int' }, { name: 'h_alpha', type: 'float' }, { name: 'h_beta', type: 'float' }, { name: 'h_hsi', type: 'float' }, @@ -913,6 +913,7 @@ }); }, ready: function() { + whirlpoolHops(); calcIBUs(); $('#jqxTabs').jqxTabs('next'); }, @@ -951,7 +952,8 @@ { text: 'IBU', datafield: 'ibu', width: 80, align: 'right', cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) { var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), - parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), $('#ibu_method').val()); + parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), $('#ibu_method').val(), + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6); return '' + dataAdapter.formatNumber(ibu, 'f1') + ''; } }, @@ -992,7 +994,8 @@ $('#wh_name').val(hopData.h_name); $('#wh_amount').val(hopData.h_amount * 1000); var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), - parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val()); + parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val(), + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6); $('#wh_ibu').val(ibu); if (hopData.h_useat == 5) // Dry hop $('#wh_time').val(hopData.h_time / 1440); @@ -1988,6 +1991,8 @@ function hopFlavourContribution(bt, vol, use, amount) { var result; + if (use == 4 || use == 5) // Whirlpool or Dry-hop + return 0; if (use == 1) { // First wort result = 0.15; // assume 15% flavourcontribution for fwh } else if (bt > 50) { @@ -2003,8 +2008,12 @@ function hopAromaContribution(bt, vol, use, amount) { var result = 0; - if (use == 5) { // Dry hop + if (use == 5) { // Dry hop result = 1.33; + } else if (use == 4) { // Whirlpool + if (bt > 30) + bt = 30; // Max 30 minutes + result = 0.62 * bt / 30; } else if (bt > 20) { result = 0; } else if (bt > 7.5) { @@ -2013,10 +2022,8 @@ result = 1; } else if (use == 3) { // Aroma result = 1.2; - } else if (use == 4) { // Whirlpool - result = 1.2; } - return (result * amount * 1000) / vol; + return (result * amount * 1000) / vol; } function calcIBUs() { @@ -2029,10 +2036,12 @@ for (i = 0; i < rows.length; i++) { row = rows[i]; total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size), - parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method); + parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method, + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6); ferm_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.brew_fermenter_volume) + parseFloat(dataRecord.brew_fermenter_tcloss), - parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method); + parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method, + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6); hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount)); hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), @@ -2408,6 +2417,22 @@ } }; + function whirlpoolHops() { + console.log('whirlpoolHops()'); + var row, i, time, rowscount; + if (!(rowscount = $('#hopGrid').jqxGrid('getdatainformation').rowscount)) + return; + if (rowscount == 0) + return; + for (i = 0; i < rowscount; i++) { + row = $('#hopGrid').jqxGrid('getrowdata', i); + if (row.h_useat == 4) { + time = parseFloat(dataRecord.brew_whirlpool9) + parseFloat(dataRecord.brew_whirlpool7) + parseFloat(dataRecord.brew_whirlpool6); + $('#hopGrid').jqxGrid('setcellvalue', i, 'h_time', time); + } + } + }; + function calcMiscs() { ok_miscs = 1; @@ -4062,6 +4087,21 @@ dataRecord.fg = parseFloat(event.args.value); calcFermentation(); }); + $('#brew_whirlpool9').on('valueChanged', function(event) { + dataRecord.brew_whirlpool9 = event.args.value; + whirlpoolHops(); + calcIBUs(); + }); + $('#brew_whirlpool7').on('valueChanged', function(event) { + dataRecord.brew_whirlpool7 = event.args.value; + whirlpoolHops(); + calcIBUs(); + }); + $('#brew_whirlpool6').on('valueChanged', function(event) { + dataRecord.brew_whirlpool6 = event.args.value; + whirlpoolHops(); + calcIBUs(); + }); $('#BLog').jqxButton({ disabled: (dataRecord.log_brew) ? false : true}); $('#FLog').jqxButton({ disabled: (dataRecord.log_fermentation) ? false : true}); } @@ -4997,7 +5037,8 @@ console.log('amount changed: ' + event.args.value + ' time:' + hopData.h_time + ' alpha:' + hopData.h_alpha); var ibu, amount = parseFloat(event.args.value) / 1000; ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), - amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val() + amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val(), + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6 ); hopData.h_amount = amount; $('#wh_ibu').val(ibu); @@ -5013,12 +5054,6 @@ $('#wh_time').val(newtime); } hopData.h_time = newtime; - } else if (hopData.h_useat == 4) { // Whirlpool - if (newtime > 120) { - newtime = 120; - $('#wh_time').val(newtime); - } - hopData.h_time = newtime; } else if (hopData.h_useat == 5) { // Dry hop if (newtime > 21) { newtime = 21; @@ -5027,7 +5062,8 @@ hopData.h_time = newtime * 1440; } ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), - parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val()); + parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val(), + dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6); // console.log("time changed: "+newtime+" final:"+hopData.h_time+" ibu:"+ibu); $('#wh_ibu').val(ibu); }); @@ -5053,7 +5089,11 @@ hopData.h_time = 0; $('#wh_time').jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $('#wh_time').val(0); - } else { // Boil, Whirlpool or Dry hop + } else if (index == 4) { // Whirlpool + hopData.h_time = (parseFloat(dataRecord.brew_whirlpool9) + parseFloat(dataRecord.brew_whirlpool7) + parseFloat(dataRecord.brew_whirlpool6)); + $('#wh_time').jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $('#wh_time').val(hopData.h_time); + } else { // Boil, Dry hop $('#wh_time').jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); } if (index == 5) // Dry hop