Added the IBU contribution for whirlpool hops.

Sun, 27 Oct 2019 20:20:09 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 27 Oct 2019 20:20:09 +0100
changeset 538
41d21817608e
parent 531
7c37a6f85d55
child 539
fe9ac6d49c4f

Added the IBU contribution for whirlpool hops.

www/js/global.js file | annotate | diff | comparison | revisions
www/js/prod_edit.js file | annotate | diff | comparison | revisions
--- 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;
 }
 
--- 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 '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, 'f1') + '</span>';
      }
     },
@@ -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

mercurial