# HG changeset patch # User Michiel Broek # Date 1651924536 -7200 # Node ID 904591820c3dfd98f054ffea34c9ea5f0b7119e5 # Parent 6a5e5b3d0fcd312109b876109d9d8d2a61d80d85 Added yeast viability calculation. diff -r 6a5e5b3d0fcd -r 904591820c3d src/EditProduct.cpp --- a/src/EditProduct.cpp Thu May 05 20:43:45 2022 +0200 +++ b/src/EditProduct.cpp Sat May 07 13:55:36 2022 +0200 @@ -331,7 +331,10 @@ product->starter_type = query.value("starter_type").toInt(); product->starter_sg = query.value("starter_sg").toDouble(); product->starter_viability = query.value("starter_viability").toInt(); - product->yeast_prod_date = query.value("yeast_prod_date").toDate(); + if (query.value("yeast_prod_date").toString().length() == 10) + product->yeast_prod_date = query.value("yeast_prod_date").toDate(); + else + product->yeast_prod_date = QDate(); product->yeast_pitchrate = query.value("yeast_pitchrate").toDouble(); product->prop_type[0] = query.value("prop1_type").toInt(); product->prop_volume[0] = query.value("prop1_volume").toDouble(); @@ -1046,6 +1049,9 @@ connect(ui->addYeast, SIGNAL(clicked()), this, SLOT(addYeastRow_clicked())); connect(ui->stmethodEdit, QOverload::of(&QComboBox::currentIndexChanged), this, &EditProduct::yeast_method_changed); connect(ui->startersgEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::yeast_starter_sg_changed); + connect(ui->productionButton1, SIGNAL(clicked()), this, SLOT(yeast_prod_date_today())); + connect(ui->productionButton2, SIGNAL(clicked()), this, SLOT(yeast_prod_date_clear())); + connect(ui->productionEdit, &QDateEdit::dateChanged, this, &EditProduct::yeast_prod_date_changed); // All signals from tab "Mash" ui->mashsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); diff -r 6a5e5b3d0fcd -r 904591820c3d src/EditProduct.h --- a/src/EditProduct.h Thu May 05 20:43:45 2022 +0200 +++ b/src/EditProduct.h Sat May 07 13:55:36 2022 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include #include "global.h" @@ -80,7 +81,9 @@ void misc_select_changed(int val); void misc_instock_changed(bool val); void misc_useat_changed(int val); - void yeast_prod_date_clicked(); + void yeast_prod_date_clear(); + void yeast_prod_date_today(); + void yeast_prod_date_changed(QDate val); void yeast_method_changed(int val); void yeast_starter_sg_changed(double val); void yeast_starter_edit_clicked(); @@ -198,6 +201,7 @@ StepResult calcStep(double svol, int stype, double start); void calcSteps(int stype, double start, double needed); void initYeast(); + void calcViability(); void calcYeast(); void adjustYeasts(double factor); double infusionVol(double step_infused, double step_mashkg, double infuse_temp, double step_temp, double last_temp); diff -r 6a5e5b3d0fcd -r 904591820c3d src/EditProductTab6.cpp --- a/src/EditProductTab6.cpp Thu May 05 20:43:45 2022 +0200 +++ b/src/EditProductTab6.cpp Sat May 07 13:55:36 2022 +0200 @@ -139,7 +139,7 @@ ui->est_og4Edit->setValue(product->est_og); ui->est_fg3Edit->setValue(product->est_fg); ui->est_abv2Edit->setValue(product->est_abv); - ui->productionEdit->setText(product->yeast_prod_date.toString("dd MMM yyyy")); + ui->productionEdit->setDate(product->yeast_prod_date); ui->conditionShow->setValue(product->starter_viability); ui->startersgEdit->setValue(product->starter_sg); ui->pitchrateEdit->setValue(product->yeast_pitchrate); @@ -187,6 +187,8 @@ if (product->yeasts.size() == 0) return; // No yeast in product. + calcViability(); + for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).y_use == YEAST_USE_PRIMARY) { // Primary if (product->yeasts.at(i).y_form == YEAST_FORMS_DRY) { @@ -236,9 +238,9 @@ ui->pitchrateEdit->setValue(product->yeast_pitchrate); } - initcells = (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * 0.97; // cells / ml. + initcells = (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100.0); if (product->yeasts.at(i).y_form == YEAST_FORMS_LIQUID) - initcells = (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * 0.97; // 97% viability assumed. + initcells = (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100.0); needed = round(product->yeast_pitchrate * volume * plato * 10.0) / 10.0; if (needed > initcells) { @@ -613,8 +615,77 @@ } -void EditProduct::yeast_prod_date_clicked() +void EditProduct::calcViability() { + double vpm = 1.00; + double max = 100; + + for (int i = 0; i < product->yeasts.size(); i++) { + if (product->yeasts.at(i).y_use == 0) { + if (product->yeasts.at(i).y_form == 0) { // Liquid + vpm = 0.80; + max = 97; + if (product->yeasts.at(i).y_laboratory == "White Labs") { // PurePitch + vpm = 0.95; + max = 100; + } + } else if (product->yeasts.at(i).y_form == 1) { // dry + vpm = 0.998; + max = 100; + } else if (product->yeasts.at(i).y_form == 6) { // dried kveik + vpm = 0.92; + max = 100; + } else { // Slant, Culture, Frozen, Bottle + vpm = 0.99; + max = 97; + } + } + } + qDebug() << "calcViability vpm:" << vpm << "max:" << max; + + double base = max; + + /* + * Calculate time days before today. If the date is cleared, + * the result is 0 days. Dates in the future are ignored. + */ + int timeDiff = product->yeast_prod_date.daysTo(QDate::currentDate()); + if (timeDiff < 0) + timeDiff == 0; + + double degrade = 1 - ((1 - vpm) / 30.41); // viability degradation per day. + for (int i = 0; i < timeDiff; i++) { + base = base * degrade; + } + if (base > max) + base = max; + base = round(base); + product->starter_viability = base; + ui->conditionShow->setValue(product->starter_viability); + qDebug() << "age" << timeDiff << "degrade" << degrade << "base" << base ; +} + + +void EditProduct::yeast_prod_date_changed(QDate val) +{ + product->yeast_prod_date = ui->productionEdit->nullDate(); + qDebug() << "yeast_prod_date_changed" << val << product->yeast_prod_date; + calcViability(); + calcYeast(); +} + + +void EditProduct::yeast_prod_date_clear() +{ + product->yeast_prod_date = QDate(); + ui->productionEdit->setDate(QDate()); +} + + +void EditProduct::yeast_prod_date_today() +{ + product->yeast_prod_date = QDate::currentDate(); + ui->productionEdit->setDate(QDate::currentDate()); } @@ -701,8 +772,6 @@ is_changed(); } - disconnect(typeEdit, nullptr, nullptr, nullptr); - disconnect(volEdit, nullptr, nullptr, nullptr); disconnect(buttonBox, nullptr, nullptr, nullptr); } diff -r 6a5e5b3d0fcd -r 904591820c3d ui/EditProduct.ui --- a/ui/EditProduct.ui Thu May 05 20:43:45 2022 +0200 +++ b/ui/EditProduct.ui Sat May 07 13:55:36 2022 +0200 @@ -2933,9 +2933,9 @@ - 320 + 370 10 - 791 + 741 261 @@ -2947,7 +2947,7 @@ - 610 + 550 10 91 24 @@ -2975,7 +2975,7 @@ - 420 + 360 10 181 20 @@ -2991,7 +2991,7 @@ - 230 + 200 10 101 23 @@ -3001,7 +3001,7 @@ - 40 + 10 10 181 20 @@ -3017,7 +3017,7 @@ - 40 + 10 40 181 20 @@ -3033,7 +3033,7 @@ - 230 + 200 40 71 24 @@ -3064,7 +3064,7 @@ - 710 + 655 10 28 22 @@ -3084,7 +3084,7 @@ - 80 + 50 100 636 146 @@ -3431,17 +3431,17 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - 280 + + + + 290 130 28 22 - Set or clear date + Set the date to today. ... @@ -3451,22 +3451,6 @@ :/icons/silk/date.png:/icons/silk/date.png - - - - 170 - 130 - 101 - 23 - - - - End of primary fermentation, start secondary. - - - true - - @@ -3491,6 +3475,48 @@ % + + 100 + + + + + + 170 + 130 + 111 + 24 + + + + Edit the production date. + + + dd-MM-yyyy + + + true + + + + + + 320 + 130 + 28 + 22 + + + + Clear the date + + + ... + + + + :/icons/silk/delete.png:/icons/silk/delete.png + @@ -10049,6 +10075,11 @@ + NullDateEdit + QDateEdit +
NullDateEdit.h
+
+ RangedSlider QWidget
RangedSlider.h