www/js/rec_edit.js

branch
stable
changeset 665
4d01937ae7af
parent 662
4bb005694ce7
child 667
1246550451ca
equal deleted inserted replaced
521:9d1aa6f3a4da 665:4d01937ae7af
1 /***************************************************************************** 1 /*****************************************************************************
2 * Copyright (C) 2018-2019 2 * Copyright (C) 2018-2020
3 * 3 *
4 * Michiel Broek <mbroek at mbse dot eu> 4 * Michiel Broek <mbroek at mbse dot eu>
5 * 5 *
6 * This file is part of BMS 6 * This file is part of BMS
7 * 7 *
31 preboil_sg = 0, 31 preboil_sg = 0,
32 last_base = '', 32 last_base = '',
33 last_acid = '', 33 last_acid = '',
34 Ka1 = 0.0000004445, 34 Ka1 = 0.0000004445,
35 Ka2 = 0.0000000000468, 35 Ka2 = 0.0000000000468,
36 error_count = 0,
36 MMCa = 40.048, 37 MMCa = 40.048,
37 MMMg = 24.305, 38 MMMg = 24.305,
38 MMNa = 22.98976928, 39 MMNa = 22.98976928,
39 MMCl = 35.453, 40 MMCl = 35.453,
40 MMSO4 = 96.0626, 41 MMSO4 = 96.0626,
46 MMMgSO4 = 246.475, 47 MMMgSO4 = 246.475,
47 MMNaHCO3 = 84.007, 48 MMNaHCO3 = 84.007,
48 MMNa2CO3 = 105.996, 49 MMNa2CO3 = 105.996,
49 MMNaCl = 58.443, 50 MMNaCl = 58.443,
50 MMCaOH2 = 74.06268; 51 MMCaOH2 = 74.06268;
51 52 data_loaded = 0;
52 53
53 function createDelElements() { 54 function createDelElements() {
54 $('#eventWindow').jqxWindow({ 55 $('#eventWindow').jqxWindow({
55 theme: theme, 56 theme: theme,
56 position: { x: 490, y: 210 }, 57 position: { x: 490, y: 210 },
72 73
73 74
74 function hopFlavourContribution(bt, vol, use, amount) { 75 function hopFlavourContribution(bt, vol, use, amount) {
75 var result; 76 var result;
76 77
78 if (use == 4 || use == 5) // Whirlpool or Dry-hop
79 return 0;
77 if (use == 1) { // First wort 80 if (use == 1) { // First wort
78 result = 0.15; // assume 15% flavourcontribution for fwh 81 result = 0.15; // assume 15% flavourcontribution for fwh
79 } else if (bt > 50) { 82 } else if (bt > 50) {
80 result = 0.10; // assume 10% flavourcontribution as a minimum 83 result = 0.10; // assume 10% flavourcontribution as a minimum
81 } else { 84 } else {
90 function hopAromaContribution(bt, vol, use, amount) { 93 function hopAromaContribution(bt, vol, use, amount) {
91 var result = 0; 94 var result = 0;
92 95
93 if (use == 5) { // Dry hop 96 if (use == 5) { // Dry hop
94 result = 1.33; 97 result = 1.33;
98 } else if (use == 4) { // Whirlpool
99 if (bt > 30)
100 bt = 30; // Max 30 minutes
101 result = 0.62 * bt / 30;
95 } else if (bt > 20) { 102 } else if (bt > 20) {
96 result = 0; 103 result = 0;
97 } else if (bt > 7.5) { 104 } else if (bt > 7.5) {
98 result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) / 4, 2)); 105 result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) / 4, 2));
99 } else if (use == 2) { // Boil 106 } else if (use == 2) { // Boil
100 result = 1; 107 result = 1;
101 } else if (use == 3) { // Aroma 108 } else if (use == 3) { // Aroma
102 result = 1.2;
103 } else if (use == 4) { // Whirlpool
104 result = 1.2; 109 result = 1.2;
105 } 110 }
106 return (result * amount * 1000) / vol; 111 return (result * amount * 1000) / vol;
107 } 112 }
108 113
269 colorh += row.f_amount * row.f_color * get_kt(row.f_color); 274 colorh += row.f_amount * row.f_color * get_kt(row.f_color);
270 colorn += (row.f_percentage / 100) * row.f_color; // For 8.6 Pt wort. 275 colorn += (row.f_percentage / 100) * row.f_color; // For 8.6 Pt wort.
271 } 276 }
272 } 277 }
273 $('#ferm_lintner').val(Math.round(parseFloat(lintner / mashkg))); 278 $('#ferm_lintner').val(Math.round(parseFloat(lintner / mashkg)));
274 //console.log('lintner:' + lintner + ' kg:' + mashkg);
275 to_100 = my_100; 279 to_100 = my_100;
276 if (to_100) { 280 if (to_100) {
277 $('#wf_amount').jqxNumberInput({ width: 90, readOnly: true, spinButtons: false }); 281 $('#wf_amount').jqxNumberInput({ width: 90, readOnly: true, spinButtons: false });
278 } else { 282 } else {
279 $('#wf_amount').jqxNumberInput({ width: 110, readOnly: false, spinButtons: true }); 283 $('#wf_amount').jqxNumberInput({ width: 110, readOnly: false, spinButtons: true });
370 return; 374 return;
371 } 375 }
372 for (i = 0; i < rows.length; i++) { 376 for (i = 0; i < rows.length; i++) {
373 row = rows[i]; 377 row = rows[i];
374 total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size), 378 total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size),
375 parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method); 379 parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method, 0, parseFloat(row.h_time), 0);
376 hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount)); 380 hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
377 hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount)); 381 hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
378 } 382 }
379 total_ibus = Round(total_ibus, 1); 383 total_ibus = Round(total_ibus, 1);
380 hop_flavour = Round(hop_flavour * 100 / 5, 1); 384 hop_flavour = Round(hop_flavour * 100 / 5, 1);
392 } 396 }
393 397
394 398
395 function adjustHops(factor) { 399 function adjustHops(factor) {
396 400
397 //console.log('adjustHops(' + factor + ')');
398 var i, row, amount, rowscount = $('#hopGrid').jqxGrid('getdatainformation').rowscount; 401 var i, row, amount, rowscount = $('#hopGrid').jqxGrid('getdatainformation').rowscount;
399 if (rowscount == 0) 402 if (rowscount == 0)
400 return; 403 return;
401 404
402 for (i = 0; i < rowscount; i++) { 405 for (i = 0; i < rowscount; i++) {
407 } 410 }
408 411
409 412
410 function adjustMiscs(factor) { 413 function adjustMiscs(factor) {
411 414
412 //console.log('adjustMiscs(' + factor + ')');
413 var i, row, amount, rowscount = $('#miscGrid').jqxGrid('getdatainformation').rowscount; 415 var i, row, amount, rowscount = $('#miscGrid').jqxGrid('getdatainformation').rowscount;
414 if (rowscount == 0) 416 if (rowscount == 0)
415 return; 417 return;
416 418
417 for (i = 0; i < rowscount; i++) { 419 for (i = 0; i < rowscount; i++) {
436 } 438 }
437 439
438 440
439 function adjustYeasts(factor) { 441 function adjustYeasts(factor) {
440 442
441 //console.log('adjustYeasts(' + factor + ')');
442 var i, row, amount, rowscount = $('#yeastGrid').jqxGrid('getdatainformation').rowscount; 443 var i, row, amount, rowscount = $('#yeastGrid').jqxGrid('getdatainformation').rowscount;
443 if (rowscount == 0) 444 if (rowscount == 0)
444 return; 445 return;
445 446
446 for (i = 0; i < rowscount; i++) { 447 for (i = 0; i < rowscount; i++) {
453 } 454 }
454 455
455 456
456 function adjustWaters(factor) { 457 function adjustWaters(factor) {
457 458
458 //console.log('adjustWaters(' + factor + ')');
459 var i, row, amount, rowscount = $('#mashGrid').jqxGrid('getdatainformation').rowscount; 459 var i, row, amount, rowscount = $('#mashGrid').jqxGrid('getdatainformation').rowscount;
460 if (rowscount == 0) 460 if (rowscount == 0)
461 return; 461 return;
462 mash_infuse = 0; 462 mash_infuse = 0;
463 for (i = 0; i < rowscount; i++) { 463 for (i = 0; i < rowscount; i++) {
488 else 488 else
489 return 0.5; 489 return 0.5;
490 } 490 }
491 491
492 492
493 function GetOptClSO4ratio() { 493 function GetOptSO4Clratio() {
494 var BUGU = GetBUGU(); 494 if (parseFloat($('#pr_sulfate').jqxNumberInput('decimal')) > 0 && parseFloat($('#pr_chloride').jqxNumberInput('decimal'))) {
495 return (-1.2 * BUGU + 1.4); 495 return (parseFloat($('#pr_sulfate').jqxNumberInput('decimal')) / parseFloat($('#pr_chloride').jqxNumberInput('decimal')));
496 } else {
497 var BUGU = GetBUGU();
498 return (-1.2 * BUGU + 1.4);
499 }
496 } 500 }
497 501
498 502
499 503
500 function setRangeIndicator(ion, rangeCode) { 504 function setRangeIndicator(ion, rangeCode) {
555 Z = ZAlkalinity(pHZ); 559 Z = ZAlkalinity(pHZ);
556 return Z - (Calc / 3.5 + Magn / 7); 560 return Z - (Calc / 3.5 + Magn / 7);
557 } 561 }
558 562
559 563
564 function BufferCapacity(di_ph, acid_to_ph_57, ebc, graintype) {
565 C1 = 0;
566 if ((di_ph != 5.7) && ((acid_to_ph_57 < - 0.1) || (acid_to_ph_57 > 0.1))) {
567 C1 = acid_to_ph_57 / (di_ph - 5.7);
568 } else {
569 // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid.
570 switch (graintype) {
571 case 0: // Base, Special, Kilned
572 case 3:
573 case 5: C1 = 0.014 * ebc - 34.192;
574 break;
575 case 2: C1 = -0.0597 * ebc - 32.457; // Crystal
576 break;
577 case 1: C1 = 0.0107 * ebc - 54.768; // Roast
578 break;
579 case 4: C1 = -149; // Sour malt
580 break;
581 }
582 }
583 return C1;
584 }
585
586
560 function ProtonDeficit(pHZ) { 587 function ProtonDeficit(pHZ) {
561 var ebc, C1, i, rows, row, Result = ZRA(pHZ) * parseFloat($('#wg_amount').jqxNumberInput('decimal')); 588 var C1, i, rows, row, Result = ZRA(pHZ) * parseFloat($('#wg_amount').jqxNumberInput('decimal'));
562 // proton deficit for the grist 589 // proton deficit for the grist
563 rows = $('#fermentableGrid').jqxGrid('getrows'); 590 if ((rows = $('#fermentableGrid').jqxGrid('getrows'))) {
564 for (i = 0; i < rows.length; i++) { 591 for (i = 0; i < rows.length; i++) {
565 row = rows[i]; 592 row = rows[i];
566 if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt 593 if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt
567 // Check if acid is required 594 C1 = BufferCapacity(row.f_di_ph, row.f_acid_to_ph_57, row.f_color, row.f_graintype);
568 C1 = 0; 595 x = C1 * (pHZ - row.f_di_ph); // AcidRequired(ZpH)
569 if ((row.f_di_ph != 5.7) && ((row.f_acid_to_ph_57 < - 0.1) || (row.f_acid_to_ph_57 > 0.1))) { 596 Result += x * row.f_amount;
570 C1 = row.f_acid_to_ph_57 / (row.f_di_ph - 5.7);
571 } else {
572 // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid.
573 ebc = row.f_color;
574 switch (row.f_graintype) {
575 case 0: // Base, Special, Kilned
576 case 3:
577 case 5: C1 = 0.014 * ebc - 34.192;
578 break;
579 case 2: C1 = -0.0597 * ebc - 32.457; // Crystal
580 break;
581 case 1: C1 = 0.0107 * ebc - 54.768; // Roast
582 break;
583 case 4: C1 = -149; // Sour malt
584 break;
585 }
586 } 597 }
587 x = C1 * (pHZ - row.f_di_ph); // AcidRequired(ZpH) 598 }
588 Result += x * row.f_amount; 599 } else {
589 } 600 error_count++;
601 if (error_count < 5)
602 console.log('ProtonDeficit(' + pHZ + ') invalid grist, return ' + Result);
590 } 603 }
591 return Result; 604 return Result;
592 } 605 }
593 606
594 607
604 pH -= deltapH; 617 pH -= deltapH;
605 else if (pd > deltapd) 618 else if (pd > deltapd)
606 pH += deltapH; 619 pH += deltapH;
607 pd = ProtonDeficit(pH); 620 pd = ProtonDeficit(pH);
608 } 621 }
622 pH = Round(pH, 6);
609 //console.log('MashpH() n: ' + n + ' pH: ' + pH); 623 //console.log('MashpH() n: ' + n + ' pH: ' + pH);
610 return pH; 624 return pH;
611 } 625 }
612
613
614 function GetAcidSpecs(AT) {
615 switch (AT) {
616 case 0: return { pK1: 3.86, pK2: 20, pK3: 20, MolWt: 90.08, AcidSG: 1214, AcidPrc: 0.88 }; // Melkzuur
617 case 1: return { pK1: -7, pK2: 20, pK3: 20, MolWt: 36.46, AcidSG: 1142, AcidPrc: 0.28 }; // Zoutzuur
618 case 2: return { pK1: 2.12, pK2: 7.20, pK3: 12.44, MolWt: 98.00, AcidSG: 1170, AcidPrc: 0.25 }; // Fosforzuur
619 case 3: return { pK1: -1, pK2: 1.92, pK3: 20, MolWt: 98.07, AcidSG: 1700, AcidPrc: 0.93 }; // Zwavelzuur
620 }
621 }
622
623
624
625 626
626 627
627 628
628 629
629 $(document).ready(function() { 630 $(document).ready(function() {
841 editHop(dataRecord); 842 editHop(dataRecord);
842 editMisc(dataRecord); 843 editMisc(dataRecord);
843 editYeast(dataRecord); 844 editYeast(dataRecord);
844 editMash(dataRecord); 845 editMash(dataRecord);
845 $('#jqxTabs').jqxTabs('next'); 846 $('#jqxTabs').jqxTabs('next');
847 data_loaded = 1;
846 }, 848 },
847 loadError: function(jqXHR, status, error) {}, 849 loadError: function(jqXHR, status, error) {},
848 beforeLoadComplete: function(records) { $('#jqxLoader').jqxLoader('open'); } 850 beforeLoadComplete: function(records) { $('#jqxLoader').jqxLoader('open'); }
849 }), 851 }),
850 852
879 { name: 'f_di_ph', type: 'float' }, 881 { name: 'f_di_ph', type: 'float' },
880 { name: 'f_acid_to_ph_57', type: 'float' }, 882 { name: 'f_acid_to_ph_57', type: 'float' },
881 { name: 'f_inventory', type: 'float' }, 883 { name: 'f_inventory', type: 'float' },
882 { name: 'f_avail', type: 'int' } 884 { name: 'f_avail', type: 'int' }
883 ], 885 ],
884 addrow: function(rowid, rowdata, position, commit) { 886 addrow: function(rowid, rowdata, position, commit) { commit(true); },
885 //console.log("fermentable addrow "+rowid); 887 deleterow: function(rowid, commit) { commit(true); },
886 commit(true); 888 updaterow: function(rowid, rowdata, commit) { commit(true); }
887 },
888 deleterow: function(rowid, commit) {
889 //console.log("fermentable deleterow "+rowid);
890 commit(true);
891 },
892 updaterow: function(rowid, rowdata, commit) {
893 //console.log("fermentable updaterow "+rowid);
894 commit(true);
895 }
896 }, 889 },
897 fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); 890 fermentableAdapter = new $.jqx.dataAdapter(fermentableSource);
898 891
899 $('#fermentableGrid').jqxGrid({ 892 $('#fermentableGrid').jqxGrid({
900 width: 1240, 893 width: 1240,
934 datarecord = fermentablelist.records[index]; 927 datarecord = fermentablelist.records[index];
935 row['f_name'] = datarecord.name; 928 row['f_name'] = datarecord.name;
936 row['f_origin'] = datarecord.origin; 929 row['f_origin'] = datarecord.origin;
937 row['f_supplier'] = datarecord.supplier; 930 row['f_supplier'] = datarecord.supplier;
938 row['f_amount'] = 0; 931 row['f_amount'] = 0;
939 row['[_cost'] = datarecord.cost; 932 row['f_cost'] = datarecord.cost;
940 row['f_type'] = datarecord.type; 933 row['f_type'] = datarecord.type;
941 row['f_yield'] = datarecord.yield; 934 row['f_yield'] = datarecord.yield;
942 row['f_color'] = datarecord.color; 935 row['f_color'] = datarecord.color;
943 row['f_coarse_fine_diff'] = datarecord.coarse_fine_diff; 936 row['f_coarse_fine_diff'] = datarecord.coarse_fine_diff;
944 row['f_moisture'] = datarecord.moisture; 937 row['f_moisture'] = datarecord.moisture;
1094 { name: 'h_myrcene', type: 'float' }, 1087 { name: 'h_myrcene', type: 'float' },
1095 { name: 'h_total_oil', type: 'float' }, 1088 { name: 'h_total_oil', type: 'float' },
1096 { name: 'h_inventory', type: 'float' }, 1089 { name: 'h_inventory', type: 'float' },
1097 { name: 'h_avail', type: 'int' } 1090 { name: 'h_avail', type: 'int' }
1098 ], 1091 ],
1099 addrow: function(rowid, rowdata, position, commit) { 1092 addrow: function(rowid, rowdata, position, commit) { commit(true); },
1100 //console.log("hop addrow "+rowid); 1093 deleterow: function(rowid, commit) { commit(true); },
1101 commit(true); 1094 updaterow: function(rowid, rowdata, commit) { commit(true); }
1102 },
1103 deleterow: function(rowid, commit) {
1104 //console.log("hop deleterow "+rowid);
1105 commit(true);
1106 },
1107 updaterow: function(rowid, rowdata, commit) {
1108 //console.log("hop updaterow "+rowid);
1109 commit(true);
1110 }
1111 }, 1095 },
1112 hopAdapter = new $.jqx.dataAdapter(hopSource); 1096 hopAdapter = new $.jqx.dataAdapter(hopSource);
1113 1097
1114 $('#hopGrid').jqxGrid({ 1098 $('#hopGrid').jqxGrid({
1115 width: 1240, 1099 width: 1240,
1224 }, 1208 },
1225 { text: 'IBU', datafield: 'ibu', width: 80, align: 'right', 1209 { text: 'IBU', datafield: 'ibu', width: 80, align: 'right',
1226 cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) { 1210 cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
1227 var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), 1211 var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')),
1228 parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), 1212 parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time),
1229 parseFloat(rowdata.h_alpha), $('#ibu_method').val()); 1213 parseFloat(rowdata.h_alpha), $('#ibu_method').val(), 0, parseFloat(rowdata.h_time), 0);
1230 return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, 'f1') + '</span>'; 1214 return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, 'f1') + '</span>';
1231 } 1215 }
1232 }, 1216 },
1233 { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right', 1217 { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right',
1234 cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) { 1218 cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
1258 $('#wh_name').val(hopData.h_name); 1242 $('#wh_name').val(hopData.h_name);
1259 $('#wh_amount').val(hopData.h_amount * 1000); 1243 $('#wh_amount').val(hopData.h_amount * 1000);
1260 var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, 1244 var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg,
1261 parseFloat($('#batch_size').jqxNumberInput('decimal')), 1245 parseFloat($('#batch_size').jqxNumberInput('decimal')),
1262 parseFloat(hopData.h_amount), parseFloat(hopData.h_time), 1246 parseFloat(hopData.h_amount), parseFloat(hopData.h_time),
1263 parseFloat(hopData.h_alpha), $('#ibu_method').val() 1247 parseFloat(hopData.h_alpha), $('#ibu_method').val(),
1248 0, parseFloat(hopData.h_time), 0
1264 ); 1249 );
1265 $('#wh_ibu').val(ibu); 1250 $('#wh_ibu').val(ibu);
1266 if (hopData.h_useat == 5) // Dry hop 1251 if (hopData.h_useat == 5) // Dry hop
1267 $('#wh_time').val(hopData.h_time / 1440); 1252 $('#wh_time').val(hopData.h_time / 1440);
1268 else 1253 else
1292 { name: 'm_time', type: 'float' }, 1277 { name: 'm_time', type: 'float' },
1293 { name: 'm_amount_is_weight', type: 'int' }, 1278 { name: 'm_amount_is_weight', type: 'int' },
1294 { name: 'm_inventory', type: 'float' }, 1279 { name: 'm_inventory', type: 'float' },
1295 { name: 'm_avail', type: 'int' } 1280 { name: 'm_avail', type: 'int' }
1296 ], 1281 ],
1297 addrow: function(rowid, rowdata, position, commit) { 1282 addrow: function(rowid, rowdata, position, commit) { commit(true); },
1298 //console.log("misc addrow "+rowid); 1283 deleterow: function(rowid, commit) { commit(true); },
1299 commit(true); 1284 updaterow: function(rowid, rowdata, commit) { commit(true); }
1300 },
1301 deleterow: function(rowid, commit) {
1302 //console.log("misc deleterow "+rowid);
1303 commit(true);
1304 },
1305 updaterow: function(rowid, rowdata, commit) {
1306 //console.log("misc updaterow "+rowid);
1307 commit(true);
1308 }
1309 }, 1285 },
1310 miscAdapter = new $.jqx.dataAdapter(miscSource, { 1286 miscAdapter = new $.jqx.dataAdapter(miscSource, {
1311 beforeLoadComplete: function(records) { 1287 beforeLoadComplete: function(records) {
1312 var i, row, data = new Array(); 1288 var i, row, data = new Array();
1313 for (i = 0; i < records.length; i++) { 1289 for (i = 0; i < records.length; i++) {
1527 { name: 'y_attenuation', type: 'float' }, 1503 { name: 'y_attenuation', type: 'float' },
1528 { name: 'y_use', type: 'int' }, 1504 { name: 'y_use', type: 'int' },
1529 { name: 'y_cells', type: 'float' }, 1505 { name: 'y_cells', type: 'float' },
1530 { name: 'y_tolerance', type: 'float' }, 1506 { name: 'y_tolerance', type: 'float' },
1531 { name: 'y_inventory', type: 'float' }, 1507 { name: 'y_inventory', type: 'float' },
1508 { name: 'y_sta1', type: 'int' },
1509 { name: 'y_bacteria', type: 'int' },
1510 { name: 'y_harvest_top', type: 'int' },
1511 { name: 'y_harvest_time', type: 'int' },
1512 { name: 'y_pitch_temperature', type: 'float' },
1513 { name: 'y_pofpos', type: 'int' },
1514 { name: 'y_zymocide', type: 'int' },
1532 { name: 'y_avail', type: 'int' } 1515 { name: 'y_avail', type: 'int' }
1533 ], 1516 ],
1534 addrow: function(rowid, rowdata, position, commit) { 1517 addrow: function(rowid, rowdata, position, commit) { commit(true); },
1535 //console.log("yeast addrow "+rowid); 1518 deleterow: function(rowid, commit) { commit(true); },
1536 commit(true); 1519 updaterow: function(rowid, rowdata, commit) { commit(true); }
1537 },
1538 deleterow: function(rowid, commit) {
1539 //console.log("yeast deleterow "+rowid);
1540 commit(true);
1541 },
1542 updaterow: function(rowid, rowdata, commit) {
1543 //console.log("yeast updaterow "+rowid);
1544 commit(true);
1545 }
1546 }, 1520 },
1547 yeastAdapter = new $.jqx.dataAdapter(yeastSource); 1521 yeastAdapter = new $.jqx.dataAdapter(yeastSource);
1548 1522
1549 $('#yeastGrid').jqxGrid({ 1523 $('#yeastGrid').jqxGrid({
1550 width: 1240, 1524 width: 1240,
1593 row['y_attenuation'] = datarecord.attenuation; 1567 row['y_attenuation'] = datarecord.attenuation;
1594 row['y_flocculation'] = datarecord.flocculation; 1568 row['y_flocculation'] = datarecord.flocculation;
1595 row['y_cells'] = datarecord.cells; 1569 row['y_cells'] = datarecord.cells;
1596 row['y_tolerance'] = datarecord.tolerance; 1570 row['y_tolerance'] = datarecord.tolerance;
1597 row['y_inventory'] = datarecord.inventory; 1571 row['y_inventory'] = datarecord.inventory;
1572 row['y_sta1'] = datarecord.sta1;
1573 row['y_bacteria'] = datarecord.bacteria;
1574 row['y_harvest_top'] = datarecord.harvest_top;
1575 row['y_harvest_time'] = datarecord.harvest_time;
1576 row['y_pitch_temperature'] = datarecord.pitch_temperature;
1577 row['y_pofpos'] = datarecord.pofpos;
1578 row['y_zymocide'] = datarecord.zymocide;
1598 $('#yeastGrid').jqxGrid('addrow', null, row); 1579 $('#yeastGrid').jqxGrid('addrow', null, row);
1599 } 1580 }
1600 $('#yaddrowbutton').jqxDropDownList('clearSelection'); 1581 $('#yaddrowbutton').jqxDropDownList('clearSelection');
1601 }); 1582 });
1602 $('#yinstockbutton').jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) }); 1583 $('#yinstockbutton').jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) });
1896 1877
1897 1878
1898 // Procedure TFrmWaterAdjustment.CalcWater2; 1879 // Procedure TFrmWaterAdjustment.CalcWater2;
1899 function calcWater() { 1880 function calcWater() {
1900 1881
1901 console.log('calcWater()'); 1882 if (! data_loaded) {
1883 console.log('calcWater(): failsave');
1884 return;
1885 }
1886
1902 var liters = 0, 1887 var liters = 0,
1903 calcium = 0, 1888 calcium = 0,
1904 magnesium = 0, 1889 magnesium = 0,
1905 sodium = 0, 1890 sodium = 0,
1906 total_alkalinity = 0, 1891 total_alkalinity = 0,
1910 ph = 0, 1895 ph = 0,
1911 RA = 0, 1896 RA = 0,
1912 frac = 0, 1897 frac = 0,
1913 TpH = 0, 1898 TpH = 0,
1914 protonDeficit = 0, 1899 protonDeficit = 0,
1915 AT, BT, result, pK1, pK2, pK3, MolWt, AcidSG, AcidPrc, 1900 AT, BT,
1916 r1d, r2d, f1d, f2d, f3d, 1901 r1d, r2d, f1d, f2d, f3d,
1917 deltapH, deltapd, pd, n, 1902 deltapH, deltapd, pd, n,
1918 piCLSO4_low, piCLSO4_high, Res, 1903 Res;
1919 wg_calcium, wg_sodium, wg_total_alkalinity, wg_chloride, wg_sulfate, wg_bicarbonate;
1920 1904
1921 if (dataRecord.w1_name == '') { 1905 if (dataRecord.w1_name == '') {
1922 return; 1906 return;
1923 } 1907 }
1924 1908
1940 chloride = dataRecord.w1_chloride; 1924 chloride = dataRecord.w1_chloride;
1941 sulfate = dataRecord.w1_sulfate; 1925 sulfate = dataRecord.w1_sulfate;
1942 total_alkalinity = dataRecord.w1_total_alkalinity; 1926 total_alkalinity = dataRecord.w1_total_alkalinity;
1943 ph = dataRecord.w1_ph; 1927 ph = dataRecord.w1_ph;
1944 } 1928 }
1929 var bicarbonate = total_alkalinity * 1.22;
1930
1931 /* Save mixed water ions for later */
1932 var wg_calcium = calcium;
1933 var wg_sodium = sodium;
1934 var wg_total_alkalinity = total_alkalinity;
1935 var wg_chloride = chloride;
1936 var wg_sulfate = sulfate;
1937 var wg_bicarbonate = bicarbonate;
1938
1945 $('#wg_amount').val(liters); 1939 $('#wg_amount').val(liters);
1946 wg_calcium = calcium;
1947 $('#wg_calcium').val(Math.round(calcium * 10) / 10); 1940 $('#wg_calcium').val(Math.round(calcium * 10) / 10);
1948 //wg_magnesium = magnesium;
1949 $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); 1941 $('#wg_magnesium').val(Math.round(magnesium * 10) / 10);
1950 wg_sodium = sodium;
1951 $('#wg_sodium').val(Math.round(sodium * 10) / 10); 1942 $('#wg_sodium').val(Math.round(sodium * 10) / 10);
1952 wg_total_alkalinity = total_alkalinity;
1953 $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); 1943 $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10);
1954 wg_chloride = chloride;
1955 $('#wg_chloride').val(Math.round(chloride * 10) / 10); 1944 $('#wg_chloride').val(Math.round(chloride * 10) / 10);
1956 wg_sulfate = sulfate;
1957 $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); 1945 $('#wg_sulfate').val(Math.round(sulfate * 10) / 10);
1958 // Note: brouwhulp has the malts included here in the result.
1959 //wg_ph = ph;
1960 $('#wg_ph').val(Round(ph, 1)); 1946 $('#wg_ph').val(Round(ph, 1));
1961 $('#wb_ph').val(Round(MashpH(), 1)); 1947
1962 bicarbonate = total_alkalinity * 1.22; 1948 var mash_ph = Round(MashpH(), 3);
1963 wg_bicarbonate = bicarbonate; 1949 console.log('Distilled water mash pH: ' + mash_ph);
1964 1950
1965 // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. 1951 /* Calculate Salt additions */
1966 // Calculate Ca 1952 if (liters > 0) {
1967 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + 1953 calcium += (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
1968 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4; 1954 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000) / liters;
1969 calcium += 1000 * RA / liters; 1955 magnesium += (parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000) / liters;
1970 1956 sodium += (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
1971 // Calculate Mg 1957 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters;
1972 RA = parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4; 1958 sulfate += (parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 +
1973 magnesium += 1000 * RA / liters; 1959 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / liters;
1974 1960 chloride += (2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 +
1975 // Calculate Na 1961 parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000) / liters;
1976 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl; 1962 }
1977 sodium += 1000 * RA / liters; 1963
1978 1964 if (dataRecord.wa_acid_name < 0 || dataRecord,wa_acid_name >= AcidTypeData.length) {
1979 // Calculate SO4
1980 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 +
1981 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4;
1982 sulfate += 1000 * RA / liters;
1983
1984 // Calculate Cl
1985 RA = 2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 +
1986 parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl;
1987 chloride += 1000 * RA / liters;
1988 // Einde noot.
1989
1990 if ($('#wa_acid_name').val() < 0 || $('#wa_acid_name').val() > 3) {
1991 $('#wa_acid_name').val(0); 1965 $('#wa_acid_name').val(0);
1992 dataRecord.wa_acid_name = 0; 1966 dataRecord.wa_acid_name = 0;
1967 dataRecord.wa_acid_perc = AcidTypeData[0].AcidPrc;
1968 $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc);
1993 } 1969 }
1994 if (last_acid == '') 1970 if (last_acid == '')
1995 last_acid = AcidTypeData[$('#wa_acid_name').val()].nl; 1971 last_acid = AcidTypeData[dataRecord.wa_acid_name].nl;
1996 1972
1997 if ($('#wa_base_name').val() < 0 || $('#wa_base_name').val() > 3) { 1973 if (parseFloat(dataRecord.wa_acid_perc) == 0) {
1974 dataRecord.wa_acid_perc = AcidTypeData[AT].AcidPrc;
1975 $('#wa_acid_perc').val(AcidTypeData[AT].AcidPrc);
1976 }
1977
1978 if (dataRecord.wa_base_name < 0 || dataRecord.wa_base_name > 3) {
1998 $('#wa_base_name').val(0); 1979 $('#wa_base_name').val(0);
1999 dataRecord.wa_base_name = 0; 1980 dataRecord.wa_base_name = 0;
2000 } 1981 }
2001 if (last_base == '') 1982 if (last_base == '')
2002 last_base = BaseTypeData[$('#wa_base_name').val()].nl; 1983 last_base = BaseTypeData[dataRecord.wa_base_name].nl;
2003 1984
2004 AT = dataRecord.wa_acid_name; 1985 AT = dataRecord.wa_acid_name;
2005 BT = dataRecord.wa_base_name; 1986 BT = dataRecord.wa_base_name;
2006 1987
2007 result = GetAcidSpecs(AT); 1988 /* Note that the next calculations do not correct the pH change by the added salts.
2008 pK1 = result.pK1; 1989 This pH change is at most 0.1 pH and is a minor difference in Acid amount. */
2009 pK2 = result.pK2;
2010 pK3 = result.pK3;
2011 MolWt = result.MolWt;
2012 AcidSG = result.AcidSG;
2013 AcidPrc = result.AcidPrc;
2014 1990
2015 if (dataRecord.calc_acid) { 1991 if (dataRecord.calc_acid) {
1992 $('.c_mashph').show();
1993 /* Auto calculate pH */
2016 TpH = parseFloat(dataRecord.mash_ph); 1994 TpH = parseFloat(dataRecord.mash_ph);
2017 protonDeficit = ProtonDeficit(TpH); 1995 protonDeficit = ProtonDeficit(TpH);
2018 console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit); 1996 console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit);
2019 if (protonDeficit > 0) { // Add acid 1997 if (protonDeficit > 0) { // Add acid
2020 $('#wa_base').val(0); 1998 $('#wa_base').val(0);
2021 setWaterAgent(last_base, 0); 1999 setWaterAgent(last_base, 0);
2022 frac = CalcFrac(TpH, pK1, pK2, pK3); 2000 frac = CalcFrac(TpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
2023 Acid = protonDeficit / frac; 2001 Acid = protonDeficit / frac;
2024 Acid *= MolWt; // mg 2002 Acid *= AcidTypeData[AT].MolWt; // mg
2025 Acidmg = Acid; 2003 Acidmg = Acid;
2026 Acid = Acid / AcidSG; // ml 2004 Acid = Acid / AcidTypeData[AT].AcidSG; // ml
2027 2005 Acid = Round(Acid / (parseFloat(dataRecord.wa_acid_perc) / 100), 2); // ml
2028 if (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) == 0) 2006 console.log('Mash auto Acid final ml: ' + Acid);
2029 $('#wa_acid_perc').val(AcidPrc); 2007 $('#wa_acid').val(Acid);
2030 Acid = Acid * AcidPrc / (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) / 100); // ml 2008 setWaterAgent(AcidTypeData[AT].nl, Acid);
2031 console.log('Final ml: ' + Acid);
2032 $('#wa_acid').val(Math.round(Acid * 100) / 100);
2033 setWaterAgent(AcidTypeData[AT].nl, Math.round(Acid * 100) / 100);
2034 2009
2035 bicarbonate = bicarbonate - protonDeficit * frac / liters; 2010 bicarbonate = bicarbonate - protonDeficit * frac / liters;
2036 total_alkalinity = bicarbonate * 50 / 61; 2011 total_alkalinity = bicarbonate * 50 / 61;
2037 } else if (protonDeficit < 0) { //Add base 2012 } else if (protonDeficit < 0) { //Add base
2038 $('#wa_acid').val(0); 2013 $('#wa_acid').val(0);
2039 setWaterAgent(last_acid, 0); 2014 setWaterAgent(last_acid, 0);
2040 r1d = Math.pow(10, (TpH - 6.38)); 2015 r1d = Math.pow(10, (TpH - 6.35));
2041 r2d = Math.pow(10, (TpH - 10.38)); 2016 r2d = Math.pow(10, (TpH - 10.33));
2042 f1d = 1 / (1 + r1d + r1d * r2d); 2017 f1d = 1 / (1 + r1d + r1d * r2d);
2043 f2d = f1d * r1d; 2018 f2d = f1d * r1d;
2044 f3d = f2d * r2d; 2019 f3d = f2d * r2d;
2045 switch (BT) { 2020 switch (BT) {
2046 case 0: RA = -protonDeficit / (f1d - f3d); //Sodiumbicarbonate, mmol totaal 2021 case 0:
2047 RA = RA * MMNaHCO3 / 1000; //gram 2022 RA = -protonDeficit / (f1d - f3d); //Sodiumbicarbonate, mmol totaal
2048 $('#wa_base').val(Round(RA, 2)); 2023 RA = RA * MMNaHCO3 / 1000; //gram
2049 setWaterAgent('NaHCO3', Round(RA, 2)); 2024 $('#wa_base').val(Round(RA, 2));
2050 if (liters > 0) { 2025 setWaterAgent('NaHCO3', Round(RA, 2));
2051 // Na 2026 if (liters > 0) {
2052 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + 2027 // Na
2053 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3; 2028 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
2054 RA = 1000 * RA / liters; 2029 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters;
2055 sodium = wg_sodium + RA; 2030 sodium = wg_sodium + RA;
2056 // HCO3 2031 // HCO3
2057 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; 2032 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3 * 1000) / liters;
2058 RA = 1000 * RA / liters; 2033 bicarbonate = wg_bicarbonate + RA;
2059 bicarbonate = wg_bicarbonate + RA; 2034 total_alkalinity = bicarbonate * 50 / 61;
2060 total_alkalinity = bicarbonate * 50 / 61; 2035 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2061 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2036 }
2062 } 2037 break;
2063 break; 2038 case 1:
2064 case 1: RA = -protonDeficit / (2 * f1d + f2d); // Sodiumcarbonate, mmol totaal 2039 RA = -protonDeficit / (2 * f1d + f2d); // Sodiumcarbonate, mmol totaal
2065 RA = RA * MMNa2CO3 / 1000; //gram 2040 RA = RA * MMNa2CO3 / 1000; //gram
2066 $('#wa_base').val(Round(RA, 2)); 2041 $('#wa_base').val(Round(RA, 2));
2067 setWaterAgent('Na2CO3', Round(RA, 2)); 2042 setWaterAgent('Na2CO3', Round(RA, 2));
2068 if (liters > 0) { 2043 if (liters > 0) {
2069 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + 2044 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
2070 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; 2045 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3 * 1000) / liters;
2071 RA = 1000 * RA / liters; 2046 sodium = wg_sodium + RA;
2072 sodium = wg_sodium + RA; 2047 // HCO3
2073 // HCO3 2048 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3 * 1000) / liters;
2074 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; 2049 bicarbonate = wg_bicarbonate + RA;
2075 RA = 1000 * RA / liters; 2050 total_alkalinity = bicarbonate * 50 / 61;
2076 bicarbonate = wg_bicarbonate + RA; 2051 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2077 total_alkalinity = bicarbonate * 50 / 61; 2052 }
2078 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2053 break;
2079 } 2054 case 2:
2080 break; 2055 RA = -protonDeficit * (f1d - f3d); // Calciumcarbonate, mmol totaal
2081 case 2: RA = -protonDeficit * (f1d - f3d); // Calciumcarbonate, mmol totaal 2056 RA = RA * MMCaCO3 / 1000; //gram
2082 RA = RA * MMCaCO3 / 1000; //gram 2057 //but only 1/3 is effective, so add 3 times as much
2083 //but only 1/3 is effective, so add 3 times as much 2058 RA = 3 * RA;
2084 RA = 3 * RA; 2059 $('#wa_base').val(Round(RA, 2));
2085 $('#wa_base').val(Round(RA, 2)); 2060 setWaterAgent('CaCO3', Round(RA, 2));
2086 setWaterAgent('CaCO3', Round(RA, 2)); 2061 if (liters > 0) {
2087 if (liters > 0) { 2062 //Bicarbonate
2088 //Bicarbonate 2063 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3 * 1000) / liters;
2089 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; 2064 bicarbonate = wg_bicarbonate + RA;
2090 RA = 1000 * RA / liters; 2065 total_alkalinity = bicarbonate * 50 / 61;
2091 bicarbonate = wg_bicarbonate + RA; 2066 //Ca precipitates out as Ca10(PO4)6(OH)2
2092 total_alkalinity = bicarbonate * 50 / 61; 2067 RA = (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
2093 //Ca precipitates out as Ca10(PO4)6(OH)2 2068 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000 +
2094 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + 2069 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaCO3 * 1000) / liters;
2095 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 + 2070 calcium = wg_calcium + RA;
2096 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaCO3; 2071 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2097 RA = 1000 * RA / liters; 2072 }
2098 calcium = wg_calcium + RA; 2073 break;
2099 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2074 case 3:
2100 } 2075 RA = -protonDeficit / 19.3; // Calciumhydroxide
2101 break; 2076 $('#wa_base').val(Round(RA, 2));
2102 case 3: RA = -protonDeficit / 19.3; // Calciumhydroxide 2077 setWaterAgent('Ca(OH)2', Round(RA, 2));
2103 $('#wa_base').val(Round(RA, 2)); 2078 if (liters > 0) {
2104 setWaterAgent('Ca(OH)2', Round(RA, 2)); 2079 // Bicarbonate
2105 if (liters > 0) { 2080 RA = -protonDeficit / liters;
2106 // Bicarbonate 2081 total_alkalinity = wg_total_alkalinity + RA;
2107 RA = -protonDeficit / liters; 2082 bicarbonate = total_alkalinity * 61 / 50;
2108 total_alkalinity = wg_total_alkalinity + RA; 2083 // Calcium
2109 bicarbonate = total_alkalinity * 61 / 50; 2084 RA = (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
2110 // Calcium 2085 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000 +
2111 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + 2086 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaOH2 * 1000) / liters;
2112 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 + 2087 calcium = wg_calcium + RA;
2113 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaOH2; 2088 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2114 RA = 1000 * RA / liters; 2089 }
2115 calcium = wg_calcium + RA; 2090 break;
2116 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2117 }
2118 break;
2119 } 2091 }
2120 } 2092 }
2121 ph = TpH; 2093 ph = TpH;
2122 $('#wb_ph').val(Math.round(ph * 10) / 10); 2094 $('#wb_ph').val(Round(ph, 2));
2095 $('#est_mash_ph').val(Round(ph, 2));
2123 } else { // Manual 2096 } else { // Manual
2097 /* Manual calculate pH */
2098 $('.c_mashph').hide();
2124 console.log('calc_acid no'); 2099 console.log('calc_acid no');
2125 // First add base salts 2100 if (parseFloat($('#wa_base').jqxNumberInput('decimal')) > 0 && liters > 0) {
2126 if (parseFloat($('#wa_base').jqxNumberInput('decimal')) > 0) { 2101 /* First add the base salts */
2127 if (liters > 0) { 2102 switch (BT) {
2128 switch (BT) { 2103 case 0: // Sodiumbicarbonate, Na
2129 case 0: // Sodiumbicarbonate, Na 2104 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
2130 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + 2105 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters;
2131 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3; 2106 sodium = wg_sodium + RA;
2132 RA = 1000 * RA / liters; 2107 // HCO3
2133 sodium = wg_sodium + RA; 2108 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3 * 1000) / liters;
2134 // HCO3 2109 bicarbonate = wg_bicarbonate + RA;
2135 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; 2110 total_alkalinity = bicarbonate * 50 / 61;
2136 RA = 1000 * RA / liters; 2111 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2137 bicarbonate = wg_bicarbonate + RA; 2112 break;
2138 total_alkalinity = bicarbonate * 50 / 61; 2113 case 1: // Sodiumcarbonate
2139 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2114 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
2140 break; 2115 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3 * 1000) / liters;
2141 case 1: // Sodiumcarbonate 2116 sodium = wg_sodium + RA;
2142 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + 2117 // HCO3
2143 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; 2118 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3 * 1000) / liters;
2144 RA = 1000 * RA / liters; 2119 bicarbonate = wg_bicarbonate + RA;
2145 sodium = wg_sodium + RA; 2120 total_alkalinity = bicarbonate * 50 / 61;
2146 // HCO3 2121 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2147 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; 2122 break;
2148 RA = 1000 * RA / liters; 2123 case 2: // Calciumcarbonate: Bicarbonate
2149 bicarbonate = wg_bicarbonate + RA; 2124 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 * 1000 / MMCaCO3) / liters;
2150 total_alkalinity = bicarbonate * 50 / 61; 2125 bicarbonate = wg_bicarbonate + RA;
2151 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2126 total_alkalinity = bicarbonate * 50 / 61;
2152 break; 2127 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium);
2153 case 2: // Calciumcarbonate: Bicarbonate 2128 // Ca
2154 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; 2129 RA = (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa * 1000 / MMCaCl2 +
2155 RA = 1000 * RA / liters; 2130 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa * 1000 / MMCaSO4 +
2156 bicarbonate = wg_bicarbonate + RA; 2131 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa * 1000 / MMCaCO3) / liters;
2157 total_alkalinity = bicarbonate * 50 / 61; 2132 calcium = wg_calcium + RA;
2158 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); 2133 break;
2159 // Ca
2160 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 +
2161 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 +
2162 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaCO3;
2163 RA = 1000 * RA / liters;
2164 calcium = wg_calcium + RA;
2165 break;
2166 }
2167 } 2134 }
2168 } 2135 }
2169 2136
2170 TpH = parseFloat(dataRecord.mash_ph); 2137 pHa = Round(ph, 3); // Adjusted water pH
2171 pHa = MashpH(); // This one is in demi water, should be in adjusted water??? 2138 // Then calculate the new pH with added acids and malts
2172 // Then calculate the new pH with added acids 2139 console.log('Mash pH: ' + pHa);
2173 if (parseFloat($('#wa_acid').jqxNumberInput('decimal')) > 0) { 2140 Acid = AcidTypeData[AT].AcidSG * (parseFloat(dataRecord.wa_acid_perc) / 100); // ml
2174 console.log('TpH: ' + TpH + ' water: ' + pHa); 2141 Acid *= parseFloat($('#wa_acid').jqxNumberInput('decimal'));
2175 Acid = parseFloat($('#wa_acid').jqxNumberInput('decimal')); 2142 Acid /= AcidTypeData[AT].MolWt; // mg
2176 if (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) == 0) 2143 Acidmg = Acid;
2177 $('#wa_acid_perc').val(AcidPrc); 2144
2178 Acid = Acid / AcidPrc * (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) / 100); // ml 2145 //find the pH where the protondeficit = protondeficit by the acid
2179 Acid *= AcidSG; // ml 2146 frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
2180 Acid /= MolWt; // mg 2147 protonDeficit = Round(Acid * frac, 3);
2181 Acidmg = Acid; 2148 //console.log('protonDeficit Acid: ' + protonDeficit + ' frac: ' + frac + ' pH: ' + pHa);
2182 2149
2183 //find the pH where the protondeficit = protondeficit by the acid 2150 deltapH = 0.001;
2184 frac = CalcFrac(pHa, pK1, pK2, pK3); 2151 deltapd = 0.1;
2185 protonDeficit = Acid * frac; 2152 pd = Round(ProtonDeficit(pHa), 6);
2186 2153 n = 0;
2187 deltapH = 0.001; 2154 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 4000)) {
2188 deltapd = 0.1;
2189 pd = ProtonDeficit(pHa);
2190 n = 0;
2191 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) {
2192 n++; 2155 n++;
2193 if (pd < (protonDeficit - deltapd)) 2156 if (pd < (protonDeficit - deltapd))
2194 pHa -= deltapH; 2157 pHa -= deltapH;
2195 else if (pd > (protonDeficit + deltapd)) 2158 else if (pd > (protonDeficit + deltapd))
2196 pHa += deltapH; 2159 pHa += deltapH;
2197 frac = CalcFrac(pHa, pK1, pK2, pK3); 2160 frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
2198 protonDeficit = Acid * frac; 2161 protonDeficit = Acid * frac;
2199 pd = ProtonDeficit(pHa); 2162 pd = ProtonDeficit(pHa);
2200 }
2201 console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa);
2202 RA = wg_bicarbonate - protonDeficit * frac / liters;
2203 bicarbonate = RA;
2204 total_alkalinity = RA * 50 / 61;
2205 ph = pHa;
2206 $('#wb_ph').val(Round(ph, 1));
2207 } 2163 }
2164 //console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa);
2165 RA = wg_bicarbonate - protonDeficit * frac / liters;
2166 bicarbonate = RA;
2167 total_alkalinity = RA * 50 / 61;
2168 ph = pHa;
2169 $('#wb_ph').val(Round(ph, 2));
2170 $('#est_mash_ph').val(Round(ph, 2));
2208 } 2171 }
2209 2172
2210 if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur 2173 if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur
2211 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + 2174 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 +
2212 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + 2175 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 +
2219 Acidmg / 1000 * MMCl / (MMCl + 1); 2182 Acidmg / 1000 * MMCl / (MMCl + 1);
2220 RA = 1000 * RA / liters; 2183 RA = 1000 * RA / liters;
2221 chloride = wg_chloride + RA; 2184 chloride = wg_chloride + RA;
2222 } 2185 }
2223 2186
2224 // 2:1 Sulfate to Chroride IPA's, Pale Ales. 2187 var BUGU = GetBUGU();
2225 // 1:1 Sulfate to Chloride Balanced 2188 $('#tgt_bu').val(Round(BUGU, 2));
2226 // 1:2 Sulfate to Chloride Malty
2227 // Note, values below are the other way, cl to so4!
2228 // So: 0.5 is IPA's, Pale Ales.
2229 // 1 Balanced
2230 // 2 Malty.
2231 $('#tgt_bu').val(Math.round(GetBUGU() * 100) / 100);
2232 // From brouwhulp. 2189 // From brouwhulp.
2233 if (GetBUGU() < 0.32) 2190 if (BUGU < 0.32)
2234 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>"); 2191 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>");
2235 else if (GetBUGU() < 0.43) 2192 else if (BUGU < 0.43)
2236 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>"); 2193 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>");
2237 else if (GetBUGU() < 0.52) 2194 else if (BUGU < 0.52)
2238 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>"); 2195 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>");
2239 else if (GetBUGU() < 0.63) 2196 else if (BUGU < 0.63)
2240 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>"); 2197 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>");
2241 else 2198 else
2242 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>"); 2199 $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>");
2243 $('#tgt_cl_so4').val(Math.round(GetOptClSO4ratio() * 10) / 10); 2200
2244 if (sulfate > 0) 2201 // Sulfate to Chloride ratio (Palmer).
2245 RA = chloride / sulfate; 2202 var OptSO4Clratio = GetOptSO4Clratio();
2203 $('#tgt_so4_cl').val(Round(OptSO4Clratio, 1));
2204 if (OptSO4Clratio < 0.4)
2205 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te moutig</span>");
2206 else if (OptSO4Clratio < 0.6)
2207 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig</span>");
2208 else if (OptSO4Clratio < 0.8)
2209 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig</span>");
2210 else if (OptSO4Clratio < 1.5)
2211 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Gebalanceerd</span>");
2212 else if (OptSO4Clratio < 2.0)
2213 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht bitter</span>");
2214 else if (OptSO4Clratio < 4.0)
2215 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Bitter</span>");
2216 else if (OptSO4Clratio < 9.0)
2217 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer bitter</span>");
2218 else
2219 $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te bitter</span>");
2220 if (chloride > 0)
2221 RA = sulfate / chloride;
2246 else 2222 else
2247 RA = 10; 2223 RA = 10;
2248 $('#got_cl_so4').val(Math.round(RA * 10) / 10); 2224 $('#got_so4_cl').val(Round(RA, 1));
2249 piCLSO4_low = 0.8 * GetOptClSO4ratio();
2250 piCLSO4_high = 1.2 * GetOptClSO4ratio();
2251 Res = 'normaal'; 2225 Res = 'normaal';
2252 if (RA < piCLSO4_low) 2226 if (RA < (0.8 * OptSO4Clratio))
2253 Res = 'laag'; 2227 Res = 'laag';
2254 else if (RA > piCLSO4_high) 2228 else if (RA > (1.2 * OptSO4Clratio))
2255 Res = 'hoog'; 2229 Res = 'hoog';
2256 setRangeIndicator('cl_so4', Res); 2230 setRangeIndicator('so4_cl', Res);
2257 2231
2258 $('#wb_calcium').val(Round(calcium, 1)); 2232 $('#wb_calcium').val(Round(calcium, 1));
2259 $('#wb_magnesium').val(Round(magnesium, 1)); 2233 $('#wb_magnesium').val(Round(magnesium, 1));
2260 $('#wb_sodium').val(Round(sodium, 1)); 2234 $('#wb_sodium').val(Round(sodium, 1));
2261 $('#wb_sulfate').val(Round(sulfate, 1)); 2235 $('#wb_sulfate').val(Round(sulfate, 1));
2305 calcSparge(); 2279 calcSparge();
2306 } 2280 }
2307 2281
2308 2282
2309 function calcSparge() { 2283 function calcSparge() {
2310 var TargetpH, Source_pH, Source_alkalinity, r1, r2, d, f1, f3, 2284
2311 r143, r243, d43, f143, f343, alkalinity, Ct, r1g, r2g, dg, f1g, f3g, 2285 /* Based on the work of ajDeLange. */
2312 Acid, AT, result, pK1, pK2, pK3, MolWt, AcidSG, AcidPrc, fract; 2286 var TargetpH = dataRecord.sparge_ph;
2313 2287 var Source_pH = dataRecord.w1_ph;
2314 // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html 2288 var Source_alkalinity = dataRecord.w1_total_alkalinity;
2315 TargetpH = dataRecord.sparge_ph;
2316 Source_pH = dataRecord.w1_ph;
2317 Source_alkalinity = dataRecord.w1_total_alkalinity;
2318 // Select watersource or fallback to the first source. 2289 // Select watersource or fallback to the first source.
2319 if (dataRecord.sparge_source == 1) { // Source 2 2290 if (dataRecord.sparge_source == 1) { // Source 2
2320 if (dataRecord.w2_ph > 0.0) { 2291 if (dataRecord.w2_ph > 0.0) {
2321 Source_pH = dataRecord.w2_ph; 2292 Source_pH = dataRecord.w2_ph;
2322 Source_alkalinity = dataRecord.w2_total_alkalinity; 2293 Source_alkalinity = dataRecord.w2_total_alkalinity;
2333 $('#sparge_source').val(0); 2304 $('#sparge_source').val(0);
2334 } 2305 }
2335 } 2306 }
2336 2307
2337 // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH 2308 // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH
2338 r1 = Math.pow(10, Source_pH - 6.38); 2309 var r1 = Math.pow(10, Source_pH - 6.35);
2339 r2 = Math.pow(10, Source_pH - 10.373); 2310 var r2 = Math.pow(10, Source_pH - 10.33);
2340 d = 1 + r1 + r1 * r2; 2311 var d = 1 + r1 + r1 * r2;
2341 f1 = 1 / d; 2312 var f1 = 1 / d;
2342 f3 = r1 * r2 / d; 2313 var f3 = r1 * r2 / d;
2343 2314
2344 //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) 2315 //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity)
2345 r143 = Math.pow(10, 4.3 - 6.38); 2316 var r143 = Math.pow(10, 4.3 - 6.35);
2346 r243 = Math.pow(10, 4.3 - 10.373); 2317 var r243 = Math.pow(10, 4.3 - 10.33);
2347 d43 = 1 + r143 + r143 * r243; 2318 var d43 = 1 + r143 + r143 * r243;
2348 f143 = 1 / d43; 2319 var f143 = 1 / d43;
2349 f343 = r143 * r243 / d43; 2320 var f343 = r143 * r243 / d43;
2350 2321
2351 //Step 3. Convert the sample alkalinity to milliequivalents/L
2352 alkalinity = Source_alkalinity / 50;
2353 //Step 4. Solve 2322 //Step 4. Solve
2354 Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143 - f1) + (f3 - f343)); 2323 //var Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143 - f1) + (f3 - f343));
2324 var Ct = Source_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
2355 2325
2356 //Step 5. Compute mole fractions at desired pH 2326 //Step 5. Compute mole fractions at desired pH
2357 r1g = Math.pow(10, TargetpH - 6.38); 2327 var r1g = Math.pow(10, TargetpH - 6.35);
2358 r2g = Math.pow(10, TargetpH - 10.373); 2328 var r2g = Math.pow(10, TargetpH - 10.33);
2359 dg = 1 + r1g + r1g * r2g; 2329 var dg = 1 + r1g + r1g * r2g;
2360 f1g = 1 / dg; 2330 var f1g = 1 / dg;
2361 f3g = r1g * r2g / dg; 2331 var f3g = r1g * r2g / dg;
2362 2332
2363 //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) 2333 //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L)
2364 Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l 2334 var Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l
2365 Acid += 0.01; // Add acid that would be required for distilled water. 2335 Acid += 0.01; // Add acid that would be required for distilled water.
2366 if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) { 2336
2337 //Step 8. Get the acid data.
2338 AT = dataRecord.sparge_acid_type;
2339 if (AT < 0 || AT >= AcidTypeData.length) {
2340 AT = 0;
2367 dataRecord.sparge_acid_type = 0; 2341 dataRecord.sparge_acid_type = 0;
2368 $('#sparge_acid_type').val(0); 2342 $('#sparge_acid_type').val(0);
2369 } 2343 dataRecord.sparge_acid_perc = AcidTypeData[0].AcidPrc;
2370 2344 $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc);
2371 //Step 8. Get the acid data. 2345 }
2372 AT = dataRecord.sparge_acid_type; 2346 var fract = CalcFrac(TargetpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
2373 result = GetAcidSpecs(AT);
2374 pK1 = result.pK1;
2375 pK2 = result.pK2;
2376 pK3 = result.pK3;
2377 MolWt = result.MolWt;
2378 AcidSG = result.AcidSG;
2379 AcidPrc = result.AcidPrc;
2380 fract = CalcFrac(TargetpH, pK1, pK2, pK3);
2381 2347
2382 //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. 2348 //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid.
2383 Acid /= fract; 2349 Acid /= fract;
2384 2350
2385 //Step 10. Multiply by molecular weight of the acid 2351 //Step 10. Multiply by molecular weight of the acid
2386 Acid *= MolWt; //mg 2352 Acid *= AcidTypeData[AT].MolWt; //mg
2387 2353
2388 Acid = Acid / AcidSG; //ml ; 88% lactic solution 2354 //Step 11. Divide by Specific Gravity and Percentage to get the final ml.
2389 f1 = dataRecord.sparge_acid_perc; 2355 Acid = Acid / AcidTypeData[AT].AcidSG / (dataRecord.sparge_acid_perc / 100); //ml
2390 if (f1 <= 0.1) 2356 Acid *= dataRecord.sparge_volume; //ml acid total
2391 f1 = AcidPrc;
2392 Acid = Acid * AcidPrc / (f1 / 100);
2393
2394 Acid *= dataRecord.sparge_volume; //ml lactic acid total
2395 Acid = Round(Acid, 2); 2357 Acid = Round(Acid, 2);
2396 dataRecord.sparge_acid_amount = Acid / 1000; 2358 dataRecord.sparge_acid_amount = Acid / 1000;
2397 $('#sparge_acid_amount').val(Acid); 2359 $('#sparge_acid_amount').val(Acid);
2398 } 2360 }
2399 2361
2491 setWaterAgent('NaCl', 0); 2453 setWaterAgent('NaCl', 0);
2492 setWaterAgent('NaCl', event.args.value); 2454 setWaterAgent('NaCl', event.args.value);
2493 calcWater(); 2455 calcWater();
2494 } 2456 }
2495 }); 2457 });
2496 $('#wa_base_name').on('change', function(event) { 2458 $('#wa_base_name').on('select', function(event) {
2497 if (event.args) { 2459 if (event.args) {
2498 var index = event.args.index; 2460 var index = event.args.index;
2499 setWaterAgent(last_base, 0); 2461 setWaterAgent(last_base, 0);
2500 last_base = BaseTypeData[index].nl; 2462 last_base = BaseTypeData[index].nl;
2501 setWaterAgent(last_base, parseFloat($('#wa_base').jqxNumberInput('decimal'))); 2463 setWaterAgent(last_base, parseFloat($('#wa_base').jqxNumberInput('decimal')));
2506 $('#wa_base').on('change', function(event) { 2468 $('#wa_base').on('change', function(event) {
2507 var name = BaseTypeData[$('#wa_base_name').val()].nl; 2469 var name = BaseTypeData[$('#wa_base_name').val()].nl;
2508 setWaterAgent(name, parseFloat(event.args.value)); 2470 setWaterAgent(name, parseFloat(event.args.value));
2509 calcWater(); 2471 calcWater();
2510 }); 2472 });
2511 $('#wa_acid_name').on('change', function(event) { 2473 $('#wa_acid_name').on('select', function(event) {
2512 if (event.args) { 2474 if (event.args) {
2513 var index = event.args.index; 2475 var index = event.args.index;
2514 setWaterAgent(last_acid, 0); 2476 setWaterAgent(last_acid, 0);
2515 last_acid = AcidTypeData[index].nl; 2477 last_acid = AcidTypeData[index].nl;
2516 setWaterAgent(last_acid, parseFloat($('#wa_acid').jqxNumberInput('decimal'))); 2478 setWaterAgent(last_acid, parseFloat($('#wa_acid').jqxNumberInput('decimal')));
2523 setWaterAgent(name, parseFloat(event.args.value)); 2485 setWaterAgent(name, parseFloat(event.args.value));
2524 calcWater(); 2486 calcWater();
2525 }); 2487 });
2526 $('#wa_acid_perc').on('change', function(event) { calcWater(); }); 2488 $('#wa_acid_perc').on('change', function(event) { calcWater(); });
2527 2489
2528 $('#color_method').on('change', function(event) { 2490 $('#color_method').on('select', function(event) {
2529 dataRecord.color_method = event.args.index; 2491 dataRecord.color_method = event.args.index;
2530 calcFermentables(); 2492 calcFermentables();
2531 }); 2493 });
2532 $('#ibu_method').on('change', function(event) { 2494 $('#ibu_method').on('select', function(event) {
2533 dataRecord.ibu_method = event.args.index; 2495 dataRecord.ibu_method = event.args.index;
2534 calcFermentables(); 2496 calcFermentables();
2535 calcIBUs(); 2497 calcIBUs();
2536 }); 2498 });
2537 $('#batch_size').on('change', function(event) { 2499 $('#batch_size').on('change', function(event) {
2538 console.log('batch_size change:' + event.args.value + ' old:' + dataRecord.batch_size); 2500 console.log('batch_size change:' + event.args.value + ' old:' + dataRecord.batch_size);
2539 var factor, new_boil = parseFloat(event.args.value) + dataRecord.boil_size - dataRecord.batch_size; 2501 var evap = (0.1 * parseFloat(event.args.value)) * dataRecord.boil_time / 60;
2540 factor = parseFloat(event.args.value) / dataRecord.batch_size; 2502 dataRecord.boil_size = parseFloat(event.args.value) + evap;
2541 dataRecord.boil_size = new_boil; 2503 var factor = parseFloat(event.args.value) / dataRecord.batch_size;
2542 $('#boil_size').val(Round(new_boil, 2)); 2504 $('#boil_size').val(Round(dataRecord.boil_size, 2));
2543 dataRecord.sparge_volume *= factor; 2505 dataRecord.sparge_volume *= factor;
2544 $('#sparge_volume').val(dataRecord.sparge_volume); 2506 $('#sparge_volume').val(dataRecord.sparge_volume);
2545 dataRecord.batch_size = parseFloat(event.args.value); 2507 dataRecord.batch_size = parseFloat(event.args.value);
2546 calcFermentablesFromOG(parseFloat($('#est_og').jqxNumberInput('decimal'))); // Keep the OG 2508 calcFermentablesFromOG(parseFloat($('#est_og').jqxNumberInput('decimal'))); // Keep the OG
2547 adjustWaters(factor); 2509 adjustWaters(factor);
2554 calcSparge(); 2516 calcSparge();
2555 calcMash(); 2517 calcMash();
2556 }); 2518 });
2557 $('#boil_time').on('change', function(event) { 2519 $('#boil_time').on('change', function(event) {
2558 console.log('boil_time change:' + parseFloat(event.args.value) + ' old:' + dataRecord.boil_time); 2520 console.log('boil_time change:' + parseFloat(event.args.value) + ' old:' + dataRecord.boil_time);
2559 var new_boil, new_evap, old_evap = parseFloat(dataRecord.boil_size) - parseFloat(dataRecord.batch_size); 2521 var new_evap = (0.1 * parseFloat(dataRecord.batch_size)) * parseFloat(event.args.value) / 60;
2560 new_evap = old_evap * (parseFloat(event.args.value) / dataRecord.boil_time); 2522 dataRecord.boil_size = parseFloat(dataRecord.batch_size) + new_evap;
2561 new_boil = parseFloat(dataRecord.batch_size) + new_evap;
2562 dataRecord.boil_time = parseFloat(event.args.value); 2523 dataRecord.boil_time = parseFloat(event.args.value);
2563 dataRecord.boil_size = new_boil; 2524 $('#boil_size').val(Round(dataRecord.boil_size, 2));
2564 $('#boil_size').val(Round(new_boil, 2));
2565 calcFermentables(); 2525 calcFermentables();
2566 // TODO: adjust the hops, miscs, yeast, water.
2567 calcIBUs(); 2526 calcIBUs();
2568 }); 2527 });
2569 $('#efficiency').on('change', function(event) { 2528 $('#efficiency').on('change', function(event) {
2570 var estog = parseFloat($('#est_og').jqxNumberInput('decimal')); 2529 var estog = parseFloat($('#est_og').jqxNumberInput('decimal'));
2571 dataRecord.efficiency = parseFloat(event.args.value); 2530 dataRecord.efficiency = parseFloat(event.args.value);
2593 }); 2552 });
2594 $('#sparge_volume').on('change', function(event) { 2553 $('#sparge_volume').on('change', function(event) {
2595 dataRecord.sparge_volume = parseFloat(event.args.value); 2554 dataRecord.sparge_volume = parseFloat(event.args.value);
2596 calcSparge(); 2555 calcSparge();
2597 }); 2556 });
2598 $('#sparge_source').on('change', function(event) { 2557 $('#sparge_source').on('select', function(event) {
2599 if (event.args) { 2558 if (event.args) {
2600 var index = event.args.index; 2559 var index = event.args.index;
2601 dataRecord.sparge_source = index; 2560 dataRecord.sparge_source = index;
2602 calcSparge(); 2561 calcSparge();
2603 } 2562 }
2604 }); 2563 });
2605 $('#sparge_acid_type').on('change', function(event) { 2564 $('#sparge_acid_type').on('select', function(event) {
2606 if (event.args) { 2565 if (event.args) {
2607 var index = event.args.index; 2566 var index = event.args.index;
2608 dataRecord.sparge_acid_type = index; 2567 dataRecord.sparge_acid_type = index;
2609 console.log('new sparge_acid_type: ' + dataRecord.sparge_acid_type); 2568 console.log('new sparge_acid_type: ' + dataRecord.sparge_acid_type);
2610 calcSparge(); 2569 calcSparge();
3300 }); 3259 });
3301 $('#wh_amount').jqxNumberInput(Spin1dec); 3260 $('#wh_amount').jqxNumberInput(Spin1dec);
3302 $('#wh_amount').on('change', function(event) { 3261 $('#wh_amount').on('change', function(event) {
3303 var ibu, amount = parseFloat(event.args.value) / 1000; 3262 var ibu, amount = parseFloat(event.args.value) / 1000;
3304 ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), 3263 ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')),
3305 amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val()); 3264 amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val(), 0, parseFloat(hopData.h_time), 0);
3306 hopData.h_amount = amount; 3265 hopData.h_amount = amount;
3307 console.log('amount changed: ' + event.args.value + ' time:' + hopData.h_time + ' alpha:' + hopData.h_alpha + ' IBU:' + ibu); 3266 console.log('amount changed: ' + event.args.value + ' time:' + hopData.h_time + ' alpha:' + hopData.h_alpha + ' IBU:' + ibu);
3308 $('#wh_ibu').val(ibu); 3267 $('#wh_ibu').val(ibu);
3309 }); 3268 });
3310 $('#wh_ibu').jqxNumberInput(Show1dec); 3269 $('#wh_ibu').jqxNumberInput(Show1dec);
3330 $('#wh_time').val(newtime); 3289 $('#wh_time').val(newtime);
3331 } 3290 }
3332 hopData.h_time = newtime * 1440; 3291 hopData.h_time = newtime * 1440;
3333 } 3292 }
3334 ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')), 3293 ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($('#batch_size').jqxNumberInput('decimal')),
3335 parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val()); 3294 parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $('#ibu_method').val(), 0, parseFloat(hopData.h_time), 0);
3336 $('#wh_ibu').val(ibu); 3295 $('#wh_ibu').val(ibu);
3337 }); 3296 });
3338 $('#wh_useat').jqxDropDownList({ 3297 $('#wh_useat').jqxDropDownList({
3339 theme: theme, 3298 theme: theme,
3340 source: HopUseAdapter, 3299 source: HopUseAdapter,
3507 y_attenuation: yeastData.y_attenuation, 3466 y_attenuation: yeastData.y_attenuation,
3508 y_use: yeastData.y_use, 3467 y_use: yeastData.y_use,
3509 y_cells: yeastData.y_cells, 3468 y_cells: yeastData.y_cells,
3510 y_tolerance: yeastData.y_tolerance, 3469 y_tolerance: yeastData.y_tolerance,
3511 y_inventory: yeastData.y_inventory, 3470 y_inventory: yeastData.y_inventory,
3471 y_sta1: yeastData.y_sta1,
3472 y_bacteria: yeastData.y_bacteria,
3473 y_harvest_top: yeastData.y_harvest_top,
3474 y_harvest_time: yeastData.y_harvest_time,
3475 y_pitch_temperature: yeastData.y_pitch_temperature,
3476 y_pofpos: yeastData.y_pofpos,
3477 y_zymocide: yeastData.y_zymocide,
3512 y_avail: yeastData.y_avail 3478 y_avail: yeastData.y_avail
3513 }; 3479 };
3514 $('#yeastGrid').jqxGrid('updaterow', rowID, row); 3480 $('#yeastGrid').jqxGrid('updaterow', rowID, row);
3515 calcFermentables(); 3481 calcFermentables();
3516 }); 3482 });
3553 yeastData.y_max_temperature = datarecord.max_temperature; 3519 yeastData.y_max_temperature = datarecord.max_temperature;
3554 yeastData.y_flocculation = datarecord.flocculation; 3520 yeastData.y_flocculation = datarecord.flocculation;
3555 yeastData.y_attenuation = datarecord.attenuation; 3521 yeastData.y_attenuation = datarecord.attenuation;
3556 yeastData.y_cells = datarecord.cells; 3522 yeastData.y_cells = datarecord.cells;
3557 yeastData.y_inventory = datarecord.inventory; 3523 yeastData.y_inventory = datarecord.inventory;
3524 yeastData.y_sta1 = datarecord.sta1;
3525 yeastData.y_bacteria = datarecord.bacteria;
3526 yeastData.y_harvest_top = datarecord.harvest_top;
3527 yeastData.y_harvest_time = datarecord.harvest_time;
3528 yeastData.y_pitch_temperature = datarecord.pitch_temperature;
3529 yeastData.y_pofpos = datarecord.pofpos;
3530 yeastData.y_zymocide = datarecord.zymocide;
3558 if (yeastData.y_form == 0) { 3531 if (yeastData.y_form == 0) {
3559 $('#wy_pmpt_amount').html('Pak(ken):'); 3532 $('#wy_pmpt_amount').html('Pak(ken):');
3560 } else if (yeastData.y_form == 1) { 3533 } else if (yeastData.y_form == 1 || yeastData.y_form == 6) {
3561 $('#wy_pmpt_amount').html('Gewicht gram:'); 3534 $('#wy_pmpt_amount').html('Gewicht gram:');
3562 } else { 3535 } else {
3563 $('#wy_pmpt_amount').html('Volume ml:'); 3536 $('#wy_pmpt_amount').html('Volume ml:');
3564 } 3537 }
3565 calcFermentables(); 3538 calcFermentables();
3739 $('#wg_amount').val(mash_infuse); 3712 $('#wg_amount').val(mash_infuse);
3740 }); 3713 });
3741 3714
3742 // Tab 7, Water 3715 // Tab 7, Water
3743 $('#tgt_bu').jqxNumberInput(Show2wat); 3716 $('#tgt_bu').jqxNumberInput(Show2wat);
3744 $('#tgt_cl_so4').jqxNumberInput(Show1wat); 3717 $('#tgt_so4_cl,#got_so4_cl').jqxNumberInput(Show1wat);
3745 $('#got_cl_so4').jqxNumberInput(Show1wat);
3746 3718
3747 // Water source 1 3719 // Water source 1
3748 $('#w1_name').jqxDropDownList({ 3720 $('#w1_name').jqxDropDownList({
3749 placeHolder: 'Kies hoofd water:', 3721 placeHolder: 'Kies hoofd water:',
3750 theme: theme, 3722 theme: theme,
3784 $('#w1_magnesium').jqxNumberInput(Show1wat); 3756 $('#w1_magnesium').jqxNumberInput(Show1wat);
3785 $('#w1_sodium').jqxNumberInput(Show1wat); 3757 $('#w1_sodium').jqxNumberInput(Show1wat);
3786 $('#w1_total_alkalinity').jqxNumberInput(Show1wat); 3758 $('#w1_total_alkalinity').jqxNumberInput(Show1wat);
3787 $('#w1_chloride').jqxNumberInput(Show1wat); 3759 $('#w1_chloride').jqxNumberInput(Show1wat);
3788 $('#w1_sulfate').jqxNumberInput(Show1wat); 3760 $('#w1_sulfate').jqxNumberInput(Show1wat);
3789 $('#w1_ph').jqxNumberInput(Show1wat); 3761 $('#w1_ph').jqxNumberInput(Show2wat);
3790 // Water source 2 3762 // Water source 2
3791 $('#w2_name').jqxDropDownList({ 3763 $('#w2_name').jqxDropDownList({
3792 placeHolder: 'Kies meng water:', 3764 placeHolder: 'Kies meng water:',
3793 theme: theme, 3765 theme: theme,
3794 source: waterlist, 3766 source: waterlist,
3829 $('#w2_magnesium').jqxNumberInput(Show1wat); 3801 $('#w2_magnesium').jqxNumberInput(Show1wat);
3830 $('#w2_sodium').jqxNumberInput(Show1wat); 3802 $('#w2_sodium').jqxNumberInput(Show1wat);
3831 $('#w2_total_alkalinity').jqxNumberInput(Show1wat); 3803 $('#w2_total_alkalinity').jqxNumberInput(Show1wat);
3832 $('#w2_chloride').jqxNumberInput(Show1wat); 3804 $('#w2_chloride').jqxNumberInput(Show1wat);
3833 $('#w2_sulfate').jqxNumberInput(Show1wat); 3805 $('#w2_sulfate').jqxNumberInput(Show1wat);
3834 $('#w2_ph').jqxNumberInput(Show1wat); 3806 $('#w2_ph').jqxNumberInput(Show2wat);
3835 // Water mixed 3807 // Water mixed
3836 $('#wg_amount').jqxNumberInput(Show1wat); 3808 $('#wg_amount').jqxNumberInput(Show1wat);
3837 $('#wg_calcium').jqxNumberInput(Show1wat); 3809 $('#wg_calcium').jqxNumberInput(Show1wat);
3838 $('#wg_magnesium').jqxNumberInput(Show1wat); 3810 $('#wg_magnesium').jqxNumberInput(Show1wat);
3839 $('#wg_sodium').jqxNumberInput(Show1wat); 3811 $('#wg_sodium').jqxNumberInput(Show1wat);
3840 $('#wg_total_alkalinity').jqxNumberInput(Show1wat); 3812 $('#wg_total_alkalinity').jqxNumberInput(Show1wat);
3841 $('#wg_chloride').jqxNumberInput(Show1wat); 3813 $('#wg_chloride').jqxNumberInput(Show1wat);
3842 $('#wg_sulfate').jqxNumberInput(Show1wat); 3814 $('#wg_sulfate').jqxNumberInput(Show1wat);
3843 $('#wg_ph').jqxNumberInput(Show1wat); 3815 $('#wg_ph').jqxNumberInput(Show2wat);
3844 // Water treated 3816 // Water treated
3845 $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); 3817 $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'});
3846 $('#wb_calcium').jqxNumberInput(Show1wat); 3818 $('#wb_calcium').jqxNumberInput(Show1wat);
3847 $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is lager dan 30.'}); 3819 $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is lager dan 30.'});
3848 $('#wb_magnesium').jqxNumberInput(Show1wat); 3820 $('#wb_magnesium').jqxNumberInput(Show1wat);
3851 $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'}); 3823 $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'});
3852 $('#wb_chloride').jqxNumberInput(Show1wat); 3824 $('#wb_chloride').jqxNumberInput(Show1wat);
3853 $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'}); 3825 $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'});
3854 $('#wb_sulfate').jqxNumberInput(Show1wat); 3826 $('#wb_sulfate').jqxNumberInput(Show1wat);
3855 $('#wb_total_alkalinity').jqxNumberInput(Show1wat); 3827 $('#wb_total_alkalinity').jqxNumberInput(Show1wat);
3856 $('#wb_ph').jqxNumberInput(Show1wat); 3828 $('#wb_ph').jqxNumberInput(Show2wat);
3857 // Water target profile 3829 // Water target profile
3858 $('#pr_name').jqxDropDownList({ 3830 $('#pr_name').jqxDropDownList({
3859 placeHolder: 'Kies doel profiel:', 3831 placeHolder: 'Kies doel profiel:',
3860 theme: theme, 3832 theme: theme,
3861 source: waterprofiles, 3833 source: waterprofiles,
3873 $('#pr_sulfate').val(datarecord.sulfate); 3845 $('#pr_sulfate').val(datarecord.sulfate);
3874 $('#pr_chloride').val(datarecord.chloride); 3846 $('#pr_chloride').val(datarecord.chloride);
3875 $('#pr_sodium').val(datarecord.sodium); 3847 $('#pr_sodium').val(datarecord.sodium);
3876 $('#pr_magnesium').val(datarecord.magnesium); 3848 $('#pr_magnesium').val(datarecord.magnesium);
3877 $('#pr_total_alkalinity').val(datarecord.total_alkalinity); 3849 $('#pr_total_alkalinity').val(datarecord.total_alkalinity);
3850 calcWater();
3878 } 3851 }
3879 }); 3852 });
3880 $('#pr_calcium').jqxNumberInput(Show1wat); 3853 $('#pr_calcium').jqxNumberInput(Show1wat);
3881 $('#pr_magnesium').jqxNumberInput(Show1wat); 3854 $('#pr_magnesium').jqxNumberInput(Show1wat);
3882 $('#pr_sodium').jqxNumberInput(Show1wat); 3855 $('#pr_sodium').jqxNumberInput(Show1wat);
3885 $('#pr_sulfate').jqxNumberInput(Show1wat); 3858 $('#pr_sulfate').jqxNumberInput(Show1wat);
3886 3859
3887 // Water agents 3860 // Water agents
3888 $('#wa_cacl2').jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.'}); 3861 $('#wa_cacl2').jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.'});
3889 $('#wa_cacl2').jqxNumberInput(Spin1dec); 3862 $('#wa_cacl2').jqxNumberInput(Spin1dec);
3890 $('#wa_caso4').jqxTooltip({ content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'}); 3863 $('#wa_caso4').jqxTooltip({
3864 content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'
3865 });
3891 $('#wa_caso4').jqxNumberInput(Spin1dec); 3866 $('#wa_caso4').jqxNumberInput(Spin1dec);
3892 $('#wa_mgso4').jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!'}); 3867 $('#wa_mgso4').jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!'});
3893 $('#wa_mgso4').jqxNumberInput(Spin1dec); 3868 $('#wa_mgso4').jqxNumberInput(Spin1dec);
3894 $('#wa_nacl').jqxTooltip({ content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'}); 3869 $('#wa_nacl').jqxTooltip({
3870 content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. ' +
3871 'Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'
3872 });
3895 $('#wa_nacl').jqxNumberInput(Spin1dec); 3873 $('#wa_nacl').jqxNumberInput(Spin1dec);
3896 $('#mash_ph').jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'}); 3874 $('#mash_ph').jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'});
3897 $('#mash_ph').jqxNumberInput(SpinpH); 3875 $('#mash_ph').jqxNumberInput(SpinpH);
3898 $('#calc_acid').jqxCheckBox({ theme: theme, width: 120, height: 23 }); 3876 $('#calc_acid').jqxCheckBox({ theme: theme, width: 120, height: 23 });
3899 $('#wa_base_name').jqxDropDownList({ 3877 $('#wa_base_name').jqxDropDownList({

mercurial