# HG changeset patch # User Michiel Broek # Date 1563195932 -7200 # Node ID 7ad669c8613c357eeb43d611b9c17e2b390f6743 # Parent 4daef9c8aa8e69c677aa376246f61729b8f8d65a# Parent d40ca78525bc06ea8a5756dc6ca27df6e2fcad6d Merged with default diff -r 4daef9c8aa8e -r 7ad669c8613c README.design --- a/README.design Sun Jun 30 20:06:42 2019 +0200 +++ b/README.design Mon Jul 15 15:05:32 2019 +0200 @@ -11,6 +11,14 @@ Export ingredienten naar xml. +Bug: + Metingen en berekeningen met afgelezen Brix waardes kloppen niet op het eind + van de vergisting. Gaat vooral fout met de Saison. + +Wish: + Giststarter bereken gist viability. + Giststarter automatisch aantal regels aanpassen bij wijzigen van de hoeveelheden. + Extra: Gisten: = Cultures? @@ -20,7 +28,7 @@ zymocide+ (K1,K2,K28 or Klus) (killer yeast gen) (Alleen in wijngist?) sta1 (diastatic) beta glucosidase -Gist typen: Brettanomyces, Wild yeast, Kviek, Spontaneous. +Gist typen: Brettanomyces, Wild yeast, Kveik, Spontaneous. Gist klasse: N/A, Saccharomyces cerevisiae, Saccharomyces pastorianus, Saccharomyces Bayanus, Nieuwe velden: diff -r 4daef9c8aa8e -r 7ad669c8613c config.status diff -r 4daef9c8aa8e -r 7ad669c8613c configure diff -r 4daef9c8aa8e -r 7ad669c8613c configure.ac diff -r 4daef9c8aa8e -r 7ad669c8613c www/js/global.js --- a/www/js/global.js Sun Jun 30 20:06:42 2019 +0200 +++ b/www/js/global.js Mon Jul 15 15:05:32 2019 +0200 @@ -725,6 +725,49 @@ +function Round(n,d) { +var m, i; +for (i = 0, m = 1; i < d; i++, m *= 10); +return Math.round(n * m) / m; +} + + +/* + * From "Rekenen aan bier" by Hans Halberstadt. + */ +var K1s = 0.384; +var K1a = -0.177; +var K1e = 0.241; +var K1g = 0.247; +var Ks = 0.1415; +var Ka1 = 0.058; +var Ka2 = 0.078; +var Ke = 0.174; +var Kg = 0.109; + +// =E2/E6+(E3/E6)*$B$24/$B$23+(E3/E6)*(E3/E6)*$B$25/$B$23+E4/E6*$B$26/$B$23+E5/E6*$B$27/$B$23 +// For Brix +function A(sugar, volume, alc, eiwit, glycerol) { + + var vol = volume * 1000; + var A = sugar/vol + (alc/vol)*Ka1/Ks + (alc/vol)*(alc/vol) * Ka2/Ks + eiwit/vol * Ke/Ks + glycerol/vol * Kg/Ks; + + console.log("A("+sugar+"."+volume+","+alc+","+eiwit+","+glycerol+"):"+A); + return A; +} + +// =E2/E6+(E3/E6)*$B$20/$B$19+E4/E6*$B$21/$B$19+E5/E6*$B$22/$B$19 +// for Plato +function B(sugar, volume, alc, eiwit, glycerol) { + + var vol = volume * 1000; + var B = sugar/vol + (alc/vol)*K1a/K1s + eiwit/vol*K1e/K1s + glycerol/vol*K1g/K1s; + + console.log("B("+sugar+"."+volume+","+alc+","+eiwit+","+glycerol+"):"+B); + return B; +} + + function ebc_to_srm(ebc) { var srm = -1.32303E-12 * Math.pow(ebc, 4) - 0.00000000291515 * Math.pow(ebc, 3) + 0.00000818515 * Math.pow(ebc, 2) + 0.372038 * ebc + 0.596351; if ((ebc < 0) || (srm < 0)) @@ -786,23 +829,12 @@ * Kleurwerking naar SRM. Niet voor Halberstadt, Naudts */ function kw_to_srm(colormethod, c) { - if(colormethod==0)// Morey - return 1.4922*Math.pow(c,0.6859); - if(colormethod==1)// Mosher - return 0.3*c+4.7; - if(colormethod==2)// Daniels - return 0.2*c+8.4; - if(colormethod==3)// Halberstadt - return 0; - if(colormethod==4)// Naudts - return 0; +if(colormethod==0)return 1.4922*Math.pow(c,0.6859);//Morey +if(colormethod==1)return 0.3*c+4.7;//Mosher +if(colormethod==2)return 0.2*c+8.4;//Daniels +return 0;//Halberstadt,Naudts } - - - -function kw_to_ebc(colormethod, c) { - return srm_to_ebc(kw_to_srm(colormethod,c)); -} +function kw_to_ebc(colormethod, c){return srm_to_ebc(kw_to_srm(colormethod,c));} @@ -811,86 +843,80 @@ */ function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method) { - var gravity = parseFloat(SG); - var liters = parseFloat(Volume); - var alpha = parseFloat(Alpha)/100; - var mass = parseFloat(Amount) * 1000; - var time = parseFloat(Boiltime); - var fmoment = 1.0; - var pfactor = 1.0; - var ibu = 0; +var gravity=parseFloat(SG); +var liters=parseFloat(Volume); +var alpha=parseFloat(Alpha)/100; +var mass=parseFloat(Amount)*1000; +var time=parseFloat(Boiltime); +var fmoment=1.0; +var pfactor=1.0; +var ibu=0; - if ((Use == 3) || (Use == 4) || (Use == 5)) { // Aroma, Whirlpool or Dry hop. - fmoment = 0.0; - } else if (Use == 0) { // Mash - fmoment += my_factor_mashhop / 100; // Brouwhulp - } else if (Use == 1) { // First wort - fmoment += my_factor_fwh / 100; // Brouwhulp, Louis, Ozzie - } +if((Use==3)||(Use==4)||(Use==5)){// Aroma, Whirlpool or Dry hop. +fmoment=0.0; +}else if(Use==0){// Mash +fmoment+=my_factor_mashhop/100;// Brouwhulp +}else if(Use==1){// First wort +fmoment+=my_factor_fwh/100;// Brouwhulp, Louis, Ozzie +} - if (Form == 0) { // Pellet - pfactor += my_factor_pellet / 100; - } - if (Form == 1 ) { // Plug - pfactor += my_factor_plug / 100; - } - if (Form == 3) { // Wet leaf - pfactor += my_factor_wethop / 100; // From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py - } +if(Form==0){// Pellet +pfactor+=my_factor_pellet/100; +} +if(Form==1){// Plug +pfactor+=my_factor_plug/100; +} +if(Form==3){// Wet leaf +pfactor+=my_factor_wethop/100;// From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py +} - if (Method == 0) { // Tinseth + if(Method==0){// Tinseth /* http://realbeer.com/hops/research.html */ var AddedAlphaAcids = (alpha * mass * 1000) / liters; var Bigness_factor = 1.65 * Math.pow( 0.000125, gravity - 1); var BoilTime_factor = ((1 - Math.exp(-0.04 * time)) / 4.15); var utiisation = Bigness_factor * BoilTime_factor; - ibu = Math.round(utiisation * AddedAlphaAcids * fmoment * pfactor * 10) / 10.0; + ibu = Round(utiisation * AddedAlphaAcids * fmoment * pfactor,1); } - if (Method == 2) { // Daniels + if(Method==2){// Daniels var boilfactor; var sgfactor; - if (Form == 2) // Leaf + if (Form==2)// Leaf boilfactor = -(0.0041*time*time)+(0.6162*time)+1.5779; else boilfactor = -(0.0051*time*time)+(0.7835*time)+1.9348; - if (gravity < 1050) - sgfactor = 0; + if (gravity<1050) + sgfactor=0; else - sgfactor = (gravity - 1050) / 200; - ibu = Math.round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) * 10) / 10; + sgfactor=(gravity-1050)/200; + ibu = Round(fmoment*((mass*(alpha*100)*boilfactor* 0.1)/(liters*(1+sgfactor))),1); } - if (Method == 1) { // Rager + if(Method==1){// Rager var boilfactor; var sgfactor; - boilfactor = fmoment * 18.11 + 13.86 * Math.tanh((time * 31.32) / 18.27); - if (gravity < 1050) - sgfactor = 0; + boilfactor = fmoment*18.11+13.86*Math.tanh((time*31.32)/18.27); + if (gravity<1050) + sgfactor=0; else - sgfactor = (gravity - 1050) / 200; - ibu = Math.round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) * 10) / 10; + sgfactor=(gravity-1050)/200; + ibu = Round((mass*(alpha*100)*boilfactor*0.1)/(liters*(1+sgfactor)),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+"):"+ibu+" fm:"+fmoment+" pf:"+pfactor); return ibu; } -function ebc_to_color(ebc) { - return srm_to_color(ebc_to_srm(ebc)); +function ebc_to_color(ebc){return srm_to_color(ebc_to_srm(ebc));} +function srm_to_color(srm){ +var i = Math.round(srm * 10); +if(i<0){ +i=0; } - - - -function srm_to_color(srm) { - - var i = Math.round(srm * 10); - if (i < 0) { - i = 0; - } - if (i > 299) { - i = 299; - } +if(i>299){ +i=299; +} /* Table copied from Brouwhulp/BrewBuddy */ var R = [ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, // 0 @@ -941,20 +967,20 @@ 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2 ]; - var color = R[i] * 65536 + G[i] * 256 + B[i]; - var result = color.toString(16).toUpperCase(); - if (result.length < 6) { - result = '0' + result; - } - result = '#' + result; - return result; +var color=R[i]*65536+G[i]*256+B[i]; +var result=color.toString(16).toUpperCase(); +if(result.length<6) { +result='0'+result; +} +result='#'+result; +return result; } function sg_to_plato(sg){return ((135.997*sg-630.272)*sg+1111.14)*sg-616.868;} function plato_to_sg(plato){return 1+(plato/(258.6-((plato/258.2)*227.1)));} -function brix_to_sg(brix){return plato_to_sg(brix/my_brix_correction);} +function brix_to_sg(brix){if(my_brix_correction>0)return plato_to_sg(brix/my_brix_correction);else return plato_to_sg(brix);} function sg_to_brix(sg){return sg_to_plato(sg)*my_brix_correction;} @@ -967,7 +993,7 @@ plato = 100 * sugars / (batch_size * sg); sg = plato_to_sg(plato); } - return Math.round(sg * 10000) / 10000; + return Round(sg,4); } @@ -1006,7 +1032,7 @@ // 0.00553 Attenuation factor percentage simple sugars // 0.547 Attenuation factor constant var AttBeer = 0.00825 * attenuation + 0.00817 * BD - 0.00684 * Temp + 0.00026 * TotTme - 0.00356 * percCara + 0.00553 * percSugar + 0.547; - var fg = Math.round((1 + (1 - AttBeer) * (og - 1)) * 10000) / 10000; + var fg = Round(1 + (1 - AttBeer) * (og - 1),4); console.log("estimate_fg("+percSugar+","+percCara+","+BD+","+TotTme+","+Temp+","+attenuation+","+og+") AttBeer:"+AttBeer+" fg:"+fg); return fg; diff -r 4daef9c8aa8e -r 7ad669c8613c www/js/prod_edit.js --- a/www/js/prod_edit.js Sun Jun 30 20:06:42 2019 +0200 +++ b/www/js/prod_edit.js Mon Jul 15 15:05:32 2019 +0200 @@ -21,25 +21,15 @@ *****************************************************************************/ -function createDelElements() { - - $('#eventWindow').jqxWindow({ - theme: theme, - position: { x: 490, y: 210 }, - width: 300, - height: 175, - resizable: false, - isModal: true, - modalOpacity: 0.4, - okButton: $('#delOk'), - cancelButton: $('#delCancel'), - initContent: function () { - $('#delOk').jqxButton({ template: "danger", width: '65px', theme: theme }); - $('#delCancel').jqxButton({ template: "success", width: '65px', theme: theme }); - $('#delCancel').focus(); - } - }); - $('#eventWindow').jqxWindow('hide'); +function createDelElements(){ +$('#eventWindow').jqxWindow({ +theme:theme,position:{x:490,y:210},width:300,height:175,resizable:false,isModal:true,modalOpacity:0.4,okButton:$('#delOk'),cancelButton:$('#delCancel'), +initContent:function(){ +$('#delOk').jqxButton({template:"danger",width:'65px',theme:theme}); +$('#delCancel').jqxButton({template:"success",width:'65px',theme:theme}); +$('#delCancel').focus();} +}); +$('#eventWindow').jqxWindow('hide'); } @@ -103,16 +93,9 @@ $('#jqxMenu').jqxMenu('destroy'); console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); - $("#jqxLoader").jqxLoader({ - width: 250, - height: 150, - isModal: true, - text: "Laden product ...", - theme: theme - }); + $("#jqxLoader").jqxLoader({width:250,height:150,isModal:true,text:"Laden product ...",theme:theme}); function calcSupplies() { - if (dataRecord.inventory_reduced > 6) { $("#ok_pmpt").hide(); return; @@ -251,7 +234,7 @@ fermentableInit = 0; $("#ferm_lintner").val(Math.round(parseFloat(lintner / mashkg))); $("#mash_kg").val(mashkg); - console.log("calcFermentables() supplies:"+ok_fermentables); + console.log("calcFermentables() supplies:"+ok_fermentables+" moutsuiker:"+sugarsm+"/"+sugarsf); to_100 = my_100; if (to_100) { $("#wf_amount").jqxNumberInput({ width: 90, readOnly: true, spinButtons: false }); @@ -306,7 +289,7 @@ if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) { var pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + top); - dataRecord.brew_fermenter_sg = Math.round(plato_to_sg(pt) * 10000) / 10000; + dataRecord.brew_fermenter_sg = Round(plato_to_sg(pt),4); $("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg); // color if (dataRecord.color_method == 4) { @@ -1778,23 +1761,17 @@ $("#sparge_acid_amount").val(Acid); } - 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); - $("#primary_svg").val(primary_svg); - if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) { - var final_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1); - $("#final_svg").val(final_svg); - var ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg); - $("#final_abv").val(ABV); - } - } - } +function calcFermentation(){ +if(dataRecord.brew_fermenter_sg<1.020)return; +var obrix=sg_to_brix(dataRecord.brew_fermenter_sg); +if ((dataRecord.primary_end_sg>0.990)&&(dataRecord.primary_end_sg0.990)&&(dataRecord.fg= 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; - } + if(dataRecord.brew_fermenter_sg>=1.020){ + OBrix=sg_to_brix(dataRecord.brew_fermenter_sg); + FBrix=parseFloat(event.args.value); +var FG=Round(1.0031-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),4); + //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); + if(FBrix>0.05){$("#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; - } + $("#final_brix").on('change',function (event){ + if(dataRecord.brew_fermenter_sg>=1.020){ + OBrix=sg_to_brix(dataRecord.brew_fermenter_sg); + FBrix=parseFloat(event.args.value); +var FG=Round(1.0031-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),4); +// Ook brouwhulp SGFerm() maar is niet in gebruik. +//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(FBrix>0.05){$("#fg").val(FG);dataRecord.fg=FG;} calcFermentation(); } }); - $("#BLog").jqxButton({ disabled: (dataRecord.log_brew) ? false:true }); - $("#FLog").jqxButton({ disabled: (dataRecord.log_fermentation) ? false:true }); + $("#fg").on('change',function (event){dataRecord.fg=parseFloat(event.args.value);calcFermentation();}); + $("#BLog").jqxButton({disabled:(dataRecord.log_brew)?false:true}); + $("#FLog").jqxButton({disabled:(dataRecord.log_fermentation)?false:true}); }; $("#styleSelect").jqxDropDownList({