# HG changeset patch # User Michiel Broek # Date 1545746799 -3600 # Node ID 15fe253ffa83aebb5527028fbfe9f3c38ce22b0c # Parent 2e4249add363230a7ba20438b49c3f863aef15e3 Estimate OG recalculation now uses the equipment profile. Added basic water calculations. diff -r 2e4249add363 -r 15fe253ffa83 www/js/prod_edit.js --- a/www/js/prod_edit.js Tue Dec 25 13:42:36 2018 +0100 +++ b/www/js/prod_edit.js Tue Dec 25 15:06:39 2018 +0100 @@ -152,19 +152,15 @@ sug2 += row.f_amount * x; } } - // if FEquipment <> NIL then /* Use this for prod_edit.js - // begin - // sug:= SGToPlato(OG) * OG / 100; //kg/l - // vol1:= FBatchSize.Value - FEquipment.TrubChillerLoss.Value; - // vol2:= vol1 + FEquipment.TopUpWater.Value + vol; - // sug:= sug * vol2; //kg in het gistvat - // sug:= sug - sug2; //kg voor toevoeging in gistvat - // if vol1 > 0 then - // sug:= sug * FBatchSize.Value / vol1; //kg in kookketel - // sug:= sug + sug2; - // end - // else - sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100; //total amount of sugars in kg + sug = sg_to_plato(OG) * OG / 100; // kg/l + vol1 = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss; + vol2 = vol1 + dataRecord.eq_top_up_water + vol; + sug = sug * vol2; // kg in het gistvat + sug = sug - sug2; // kg voor toevoeging in gistvat + if (vol1 > 0) + sug = sug * dataRecord.batch_size / vol1; //kg in kookketel + sug = sug + sug2; + // sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100; //total amount of sugars in kg tot = 0; d = 0; @@ -309,12 +305,321 @@ $("#brew_mash_efficiency").val(0); }; + function setWaterAgent(name, amount) { + console.log("setWaterAgent(" + name + ", " + amount + ")"); + var rows = $('#miscGrid').jqxGrid('getrows'); + if (amount == 0) { + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; + if (row.m_name == name) { + var id = $("#miscGrid").jqxGrid('getrowid', i); + // console.log("name found, erase "+ id); + var commit = $("#miscGrid").jqxGrid('deleterow', id); + // console.log("result: "+commit); + } + } + } else { + var found = false; + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; + if (row.m_name == name) { + found = true; + $("#miscGrid").jqxGrid('setcellvalue', i, 'm_weight', amount); + $("#miscGrid").jqxGrid('setcellvalue', i, 'm_amount', amount / 1000); + break; + } + } + console.log("set something, found: "+found); + if (! found) { + var miscs = new $.jqx.dataAdapter(miscInvSource, { + loadComplete: function () { + var records = miscs.records; + for (var i = 0; i < records.length; i++) { + var record = records[i]; + if (record.name == name) { + var row = {}; + row["m_name"] = record.name; + row["m_amount"] = amount / 1000; + row["m_cost"] = record.cost; + row["m_type"] = record.type; + row["m_use_use"] = record.use_use; + row["m_time"] = 0; + row["m_weight"] = amount; + row["m_amount_is_weight"] = record.amount_is_weight; + var commit = $("#miscGrid").jqxGrid('addrow', null, row); + } + } + } + }); + miscs.dataBind(); + return; + } + } + } + + function setRangeIndicator(ion, rangeCode) { + $("#wr_" + ion).html("" + rangeCode + ""); + } + + function mix(v1, v2, c1, c2) { + if ((v1 + v2) > 0) { + return ((v1 * c1) + (v2 * c2)) / (v1 + v2); + } + return 0; + } + + // pH calculations + + function calcWater() { + + console.log("calcWater()"); + var liters = 0; + var calcium = 0; + var magnesium = 0; + var sodium = 0; + var total_alkalinity = 0; + var chloride = 0; + var sulfate = 0; + var ph = 0; + var RA = 0; + var acid = 0; + var frac = 0; + var MolWt = 0; + var pK1 = 0; + var pK2 = 0; + var pK3 = 0; + var TpH = 0; + var AcidSG = 0; + var AcidPrc = 0; + var protonDeficit = 0; + + if (dataRecord.w1_name != "") { + if (dataRecord.w2_name != "") { + liters = dataRecord.w1_amount + dataRecord.w2_amount; + calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); + magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); + sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); + chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); + sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); + total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); + ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); + } else { + liters = dataRecord.w1_amount; + calcium = dataRecord.w1_calcium; + magnesium = dataRecord.w1_magnesium; + sodium = dataRecord.w1_sodium; + chloride = dataRecord.w1_chloride; + sulfate = dataRecord.w1_sulfate; + total_alkalinity = dataRecord.w1_total_alkalinity; + ph = dataRecord.w1_ph; + } + } + $('#wg_amount').val(liters); + $('#wg_calcium').val(Math.round(calcium * 10) / 10); + $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); + $('#wg_sodium').val(Math.round(sodium * 10) / 10); + $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); + $('#wg_chloride').val(Math.round(chloride * 10) / 10); + $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); + // Note: brouwhulp has the malts included here in the result. + $('#wg_ph').val(Math.round(ph * 10) / 10); + + // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. + // Calculate Ca + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; + calcium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); + + // Calculate Mg + RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; + magnesium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); + + // Calculate Na + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; + sodium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); + + // Calculate SO4 + RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + + parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; + sulfate += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); + + // Calculate Cl + RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + + parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; + chloride += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); + // Einde noot. + + TpH = parseFloat(dataRecord.mash_ph); + if (TpH < 5.0 || TpH > 6.0) { + TpH = 5.4; + dataRecord.mash_ph = 5.4; + $("#mash_ph").val(5.4); + $("#tgt_mash_ph").val(5.4); + } + var acid_amount = parseFloat($("#wa_acid").jqxNumberInput('decimal')); + var acid_perc = parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')); + + switch ($("#wa_acid_name").val()) { + case 'Melkzuur': pK1 = 3.08; + pK2 = 20; + pK3 = 20; + MolWt = 90.08; + AcidSG = 1214; //@88% + AcidPrc = 0.88; + //frac = CalcFrac(TpH, pK1, pK2, pK3); + acid += acid_amount * acid_perc / 100 * AcidSG / MolWt * frac / liters; //mEq/l + break; + + case 'Zoutzuur': pK1 = -10; + pK2 = 20; + pK3 = 20; + MolWt = 36.46; + AcidSG = 1142; //@28% + AcidPrc = 0.28; + //frac = CalcFrac(TpH, pK1, pK2, pK3); + Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; + acid += Acidmg / MolWt * frac; //mEq/l + chloride += Acidmg / 1000 * MMCl / (MMCl + 1); + break; + + case 'Fosforzuur': pK1 = 2.12; + pK2 = 7.20; + pK3 = 12.44; + MolWt = 98.00; + AcidSG = 1170; //@25% + AcidPrc = 0.25; + //frac = CalcFrac(TpH, pK1, pK2, pK3); + Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; + acid += Acidmg / MolWt * frac; //mEq/l + break; + + case 'Zwavelzuur': pK1 = -10; + pK2 = 1.92; + pK3 = 20; + MolWt = 98.07; + AcidSG = 1700; //@93% + AcidPrc = 0.93; + //frac = CalcFrac(TpH, pK1, pK2, pK3); + Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; + acid += Acidmg / MolWt * frac; //mEq/l + sulfate += Acidmg / 1000 * MMSO4 / (MMSO4 + 2); + break; + } + //protonDeficit = ProtonDeficit(TpH); + //console.log("frac: "+frac+" acid: "+acid+" protonDeficit: "+protonDeficit); + //total_alkalinity -= 50 / 61 * protonDeficit * frac / liters; + + $('#wb_calcium').val(Math.round(calcium * 10) / 10); + $('#wb_magnesium').val(Math.round(magnesium * 10) / 10); + $('#wb_sodium').val(Math.round(sodium * 10) / 10); + $('#wb_sulfate').val(Math.round(sulfate * 10) / 10); + $('#wb_chloride').val(Math.round(chloride * 10) / 10); + $('#wb_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); + + if (calcium < 40) { + setRangeIndicator("calcium", "low"); + } else if (calcium > 150) { + setRangeIndicator("calcium", "high"); + } else { + setRangeIndicator("calcium", "normal"); + } + if (magnesium >= 0 && magnesium <= 30) { + setRangeIndicator("magnesium", "normal"); + } else { + setRangeIndicator("magnesium", "high"); + } + if (sodium <= 150) { + setRangeIndicator("sodium", "normal"); + } else { + setRangeIndicator("sodium", "high"); + } + if (chloride <= 100) { + setRangeIndicator("chloride", "normal"); + } else { + setRangeIndicator("chloride", "high"); + } + if (sulfate <= 350) { + setRangeIndicator("sulfate", "normal"); + } else { + setRangeIndicator("sulfate", "high"); + } + } + function calcInit () { console.log("calc.init()"); calcSGendMash(); calcMashEfficiency(); + $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); + $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); + // Fix tap water if zero using mash infuse amount. + if (parseFloat($("#wg_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { + $("#w1_amount").val(mash_infuse); + dataRecord.w1_amount = mash_infuse; + $("#wg_amount").val(mash_infuse); + $("#w2_amount").val(0); + dataRecord.w2_amount = 0; + } + calcWater(); + $("#w2_amount").on('change', function (event) { + var newval = parseFloat(event.args.value); + + if (newval > mash_infuse) { + $("#w2_amount").val(dataRecord.w2_amount); + return; + } + dataRecord.w1_amount = parseFloat($("#wg_amount").jqxNumberInput('decimal')) - newval; + $("#w1_amount").val(dataRecord.w1_amount); + dataRecord.w2_amount = newval; + console.log("new: "+event.args.value+" w1: "+dataRecord.w1_amount+" w2: "+dataRecord.w2_amount); + calcWater(); + }); + $('#wa_cacl2').on('change', function (event) { + setWaterAgent('CaCl2', event.args.value); + calcWater(); + }); + $('#wa_caso4').on('change', function (event) { + setWaterAgent('CaSO4', event.args.value); + calcWater(); + }); + $('#wa_mgso4').on('change', function (event) { + setWaterAgent('MgSO4', event.args.value); + calcWater(); + }); + $('#wa_nacl').on('change', function (event) { + setWaterAgent('NaCl', event.args.value); + calcWater(); + }); + $('#wa_base_name').on('change', function (event) { + setWaterAgent(last_base, 0); + last_base = event.args.item.value; + setWaterAgent(last_base, parseFloat($("#wa_base").jqxNumberInput('decimal'))); + calcWater(); + }); + $('#wa_base').on('change', function (event) { + setWaterAgent($("#wa_base_name").val(), parseFloat(event.args.value)); + calcWater(); + }); + $('#wa_acid_name').on('change', function (event) { + setWaterAgent(last_acid, 0); + last_acid = event.args.item.value; + setWaterAgent(last_acid, parseFloat($("#wa_acid").jqxNumberInput('decimal'))); + calcWater(); + }); + $('#wa_acid').on('change', function (event) { + setWaterAgent($("#wa_acid_name").val(), parseFloat(event.args.value)); + calcWater(); + }); + $('#wa_acid_perc').on('change', function (event) { calcWater(); }); + + $('#color_method').on('change', function (event) { calcFermentables(); }); + $('#ibu_method').on('change', function (event) { + calcFermentables(); + calcIBUs(); + }); + $('#batch_size').on('change', function (event) { console.log("batch_size change:"+event.args.value+" old:"+dataRecord.batch_size); var new_boil = parseFloat(event.args.value) + dataRecord.boil_size - dataRecord.batch_size; @@ -360,7 +665,7 @@ $('#mash_ph').on('change', function (event) { dataRecord.mash_ph = parseFloat(event.args.value); $("#tgt_mash_ph").val(parseFloat(event.args.value)); - // calcWater(); + calcWater(); }); };