# HG changeset patch # User Michiel Broek # Date 1652986236 -7200 # Node ID 54828816233fbcfea8ca06496bdf46a5a2038587 # Parent 7792a410a277c9911e83d81c5727077770bf628a Added bottles priming calculations. diff -r 7792a410a277 -r 54828816233f src/EditProduct.cpp --- a/src/EditProduct.cpp Wed May 18 22:21:16 2022 +0200 +++ b/src/EditProduct.cpp Thu May 19 20:50:36 2022 +0200 @@ -1150,6 +1150,11 @@ connect(ui->pack_addabvEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_infusion_abv_changed); connect(ui->pack_notesEdit, &QLineEdit::textChanged, this, &EditProduct::pack_infusion_txt_changed); connect(ui->pack_abvShow, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_abv_changed); + connect(ui->bottle_volumeEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_volume_changed); + connect(ui->bottle_carbEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_co2_changed); + connect(ui->bottle_sugarEdit, QOverload::of(&QComboBox::currentIndexChanged), this, &EditProduct::bottle_sugar_changed); + connect(ui->bottle_sug_waterEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_water_changed); + connect(ui->bottle_tempEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_temp_changed); /* All signals from tab Tasting */ @@ -1606,7 +1611,7 @@ obj.insert("f_name", product->fermentables.at(i).f_name); obj.insert("f_origin", product->fermentables.at(i).f_origin); obj.insert("f_supplier", product->fermentables.at(i).f_supplier); - obj.insert("f_amount", round(product->fermentables.at(i).f_amount * 10000) / 10000); + obj.insert("f_amount", round(product->fermentables.at(i).f_amount * 100000) / 100000); obj.insert("f_cost", round(product->fermentables.at(i).f_cost * 1000) / 1000); obj.insert("f_type", product->fermentables.at(i).f_type); obj.insert("f_yield", round(product->fermentables.at(i).f_yield * 10) / 10); diff -r 7792a410a277 -r 54828816233f src/EditProduct.h --- a/src/EditProduct.h Wed May 18 22:21:16 2022 +0200 +++ b/src/EditProduct.h Thu May 19 20:50:36 2022 +0200 @@ -291,6 +291,10 @@ void calcEfficiencyAfterBoil(); void brew_volume_calc(double volume, double kettle_volume, double kettle_height, double est_volume, bool aboil); double get_fg(double gravity); + double ResCO2(double T); + double CarbCO2toS(double CO2, double T, double SFactor); + double GetPressure(double CO2, double T1, double T2); + double CarbCO2ToPressure(double CO2, double T); void calcPack(); }; diff -r 7792a410a277 -r 54828816233f src/EditProductTab11.cpp --- a/src/EditProductTab11.cpp Wed May 18 22:21:16 2022 +0200 +++ b/src/EditProductTab11.cpp Thu May 19 20:50:36 2022 +0200 @@ -17,10 +17,67 @@ * along with this program. If not, see . */ +double EditProduct::ResCO2(double T) +{ + double F = T * 1.8 + 32; + return round((3.0378 - 0.050062 * F + 0.00026555 * F * F) * 1000000.0) / 1000000.0; +} + + +double EditProduct::CarbCO2toS(double CO2, double T, double SFactor) +{ + //var sugar = SFactor * (CO2 - ResCO2(CO2, T)) / 0.286; + double sugar = round((SFactor * (CO2 - ResCO2(T)) * 4.014094) * 1000000.0) / 1000000.0; + if (sugar < 0) + sugar = 0; + return sugar; //Round(sugar, 3); +} + + +double EditProduct::GetPressure(double CO2, double T1, double T2) +{ + double V = CO2 - ResCO2(T1); + V = CO2; // TODO: temp only total pressure, testing + if (V < 0) + return 0; + + double P = -1.09145427669121 + 0.00800006989646477 * T2 + 0.000260276315484684 * T2 * T2 + 0.0215142075945119 * T2 * V + + 0.674996600795854 * V + -0.00471757220150754 * V * V; + if (P < 0) + P = 0; + P = round((P * 1.01325) * 100.0) / 100.0; // atm to bar + qDebug() << " GetPressure(" << CO2 << "," << T1 << "," << T2 << ") V:" << V << "Bar:" << P << "ignored ResCO2:" << ResCO2(T1); + return P; +} + + +double EditProduct::CarbCO2ToPressure(double CO2, double T) +{ + return (CO2 - (-0.000005594056 * pow(T, 4) + 0.000144357886 * pow(T, 3) + + 0.000362999168 * T * T - 0.064872987645 * T + 1.641145175049)) / + (0.00000498031 * pow(T, 4) - 0.00024358267 * pow(T, 3) + 0.00385867329 * T * T - 0.05671206825 * T + 1.53801423376); +} + void EditProduct::calcPack() { -// qDebug() << "calcPack()" << product->package_volume << product->package_abv << "inf" << product->package_infuse_amount << product->package_infuse_abv; + int i, j; + bool found1, found2; + QSqlQuery query; + double TSec, SFactor; + + qDebug() << "calcPack()" << product->package_volume << product->package_abv << "inf" << product->package_infuse_amount << product->package_infuse_abv; + + if (product->package_volume < 1) { + /* + * If there is not enough to package, then don't + * do any calculations and clear the rest of the form. + */ + product->package_volume = 0; + ui->pack_finalabvShow->setValue(0); + + return; + } double bvol = product->package_volume - (product->package_abv * product->package_volume) / 100.0; double balc = product->package_volume - bvol; @@ -31,6 +88,90 @@ product->final_abv = round(talc / (tvol + talc) * 10000.0) / 100.0; ui->pack_finalabvShow->setValue(product->final_abv); + + TSec = product->secondary_temp; + if (TSec < 1) + TSec = product->primary_end_temp; + if (TSec < 1) + TSec = 18; + + /* + * For bottles and kegs use the following complicated procedure to + * find the needed priming sugars. + * + * 1. If we need a priming sugar then first see in the fermentables + * table if there is one selected. If not, clear sugars and done. + * 2. Then, we update the data from the fermentables inventory. + * 3. Set the found sugar in the pulldown menu. + * 4. Calculate the sugar in gr/L and total amount need. + * 5. Calculate the ABV in the bottles/kegs. + * 6. Calculate the pressure build by the refermentation. + * + * Note that this is all a leftover from the web based application that + * did work like this. It's a bit strange but it will allways give + * the right data and sugar concentrations. + * Sometimes bugs have good things. + */ + found1 = false; + if (product->bottle_amount) { + for (i = 0; i < product->fermentables.size(); i++) { + if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE) { + found1 = true; + break; + } + } + if (found1) { + SFactor = 1 / ((product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100)); + qDebug() << " bottle sugar" << product->fermentables.at(i).f_name << SFactor << TSec; + + query.prepare("SELECT name,supplier FROM inventory_fermentables WHERE type = '1' OR type = '3' ORDER BY name"); // Sugars or dry extract + query.exec(); + j = 0; + found2 = false; + while (query.next()) { + j++; + if (query.value(0).toString() == product->fermentables.at(i).f_name && query.value(1).toString() == product->fermentables.at(i).f_supplier) { + ui->bottle_sugarEdit->setCurrentIndex(j); + product->bottle_priming_sugar = j; + found2 = true; + break; + } + } + if (! found2) { + ui->bottle_sugarEdit->setCurrentIndex(0); // Make sure not selected + product->fermentables.removeAt(i); // Remove false fermentable + refreshFermentables(); + } else { + product->bottle_priming_amount = CarbCO2toS(product->bottle_carbonation, TSec, SFactor); + ui->bottle_sug_amountShow->setValue(product->bottle_priming_amount); + double total = round(product->bottle_priming_amount * product->bottle_amount * 100.0) / 100000.0; + qDebug() << " total" << total << product->fermentables.at(i).f_amount; + if (total != product->fermentables.at(i).f_amount) { + qDebug() << " update priming sugar" << total; + product->fermentables[i].f_amount = total; + refreshFermentables(); + ui->bottle_sug_weightShow->setValue(total * 1000); + is_changed(); + } + + double pabv = product->final_abv + product->bottle_priming_amount * 0.47 / 7.907; + double pvol = product->bottle_amount - (pabv * product->bottle_amount) / 100; + talc = product->bottle_amount - pvol; + tvol = pvol + product->bottle_priming_water; + ui->bottle_abvShow->setValue(talc / (tvol + talc) * 100); + ui->bottle_barShow->setValue(GetPressure(product->bottle_carbonation, TSec, product->bottle_carbonation_temp)); + } + } + } + if (! found1) { + qDebug() << " no bottle priming"; + ui->bottle_sug_amountShow->setValue(0); + ui->bottle_sug_weightShow->setValue(0); + ui->bottle_abvShow->setValue(0); + ui->bottle_barShow->setValue(0); + } + + // keg_amount keg_carbonation keg_priming_sugar keg_priming_amount keg_priming_water keg_carbonation_temp keg_forced_carb keg_pressure } @@ -105,11 +246,17 @@ void EditProduct::bottle_volume_changed(double val) { + product->bottle_amount = val; + calcPack(); + is_changed(); } void EditProduct::bottle_co2_changed(double val) { + product->bottle_carbonation = val; + calcPack(); + is_changed(); } @@ -120,11 +267,17 @@ void EditProduct::bottle_water_changed(double val) { + product->bottle_priming_water = val; + calcPack(); + is_changed(); } void EditProduct::bottle_temp_changed(double val) { + product->bottle_carbonation_temp = val; + calcPack(); + is_changed(); } diff -r 7792a410a277 -r 54828816233f ui/EditProfileWater.ui --- a/ui/EditProfileWater.ui Wed May 18 22:21:16 2022 +0200 +++ b/ui/EditProfileWater.ui Thu May 19 20:50:36 2022 +0200 @@ -430,7 +430,7 @@ 730 290 - 121 + 111 24 @@ -440,6 +440,9 @@ true + + QAbstractSpinBox::NoButtons + false diff -r 7792a410a277 -r 54828816233f ui/EditWater.ui --- a/ui/EditWater.ui Wed May 18 22:21:16 2022 +0200 +++ b/ui/EditWater.ui Thu May 19 20:50:36 2022 +0200 @@ -553,7 +553,7 @@ 730 290 - 121 + 111 24 @@ -563,6 +563,9 @@ true + + QAbstractSpinBox::NoButtons + false