24 QWidget* pWidget; |
24 QWidget* pWidget; |
25 QHBoxLayout* pLayout; |
25 QHBoxLayout* pLayout; |
26 QTableWidgetItem *item; |
26 QTableWidgetItem *item; |
27 QIcon down_icon, up_icon; |
27 QIcon down_icon, up_icon; |
28 |
28 |
|
29 qDebug() << "refreshMashs" << recipe->mashs.size(); |
|
30 |
29 down_icon.addFile(QString::fromUtf8(":/icons/silk/bullet_arrow_down.png"), QSize(), QIcon::Normal, QIcon::Off); |
31 down_icon.addFile(QString::fromUtf8(":/icons/silk/bullet_arrow_down.png"), QSize(), QIcon::Normal, QIcon::Off); |
30 up_icon.addFile(QString::fromUtf8(":/icons/silk/bullet_arrow_up.png"), QSize(), QIcon::Normal, QIcon::Off); |
32 up_icon.addFile(QString::fromUtf8(":/icons/silk/bullet_arrow_up.png"), QSize(), QIcon::Normal, QIcon::Off); |
31 |
|
32 qDebug() << "refreshYeasts" << recipe->yeasts.size(); |
|
33 std::sort(recipe->yeasts.begin(), recipe->yeasts.end(), yeast_sort_test); |
|
34 |
33 |
35 /* |
34 /* |
36 * During filling the table turn off the cellChanged signal because every cell that is filled |
35 * During filling the table turn off the cellChanged signal because every cell that is filled |
37 * triggers the cellChanged signal. The QTableWidget has no better signal to use. |
36 * triggers the cellChanged signal. The QTableWidget has no better signal to use. |
38 */ |
37 */ |
157 ui->mashsTable->setCellWidget(i, 13, pWidget); |
156 ui->mashsTable->setCellWidget(i, 13, pWidget); |
158 } |
157 } |
159 } |
158 } |
160 |
159 |
161 |
160 |
|
161 double EditRecipe::infusionVol(double step_infused, double step_mashkg, double infuse_temp, double step_temp, double last_temp) |
|
162 { |
|
163 double a = last_temp * (eq_tun_weight * eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt); |
|
164 double b = step_temp * (eq_tun_weight * eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt); |
|
165 double vol = round(((b - a) / ((infuse_temp - step_temp) * SpecificHeatWater)) * 100.0) / 100.0; |
|
166 |
|
167 if (vol < 0) |
|
168 vol = 0; |
|
169 qDebug() << " infusionVol(" << step_infused << "," << step_mashkg << "," << infuse_temp <<"," << step_temp << "," << last_temp << "):" << vol; |
|
170 return vol; |
|
171 } |
|
172 |
|
173 |
|
174 double EditRecipe::decoctionVol(double step_volume, double step_temp, double prev_temp) |
|
175 { |
|
176 double a = (eq_tun_weight * eq_tun_specific_heat + step_volume * SpecificHeatWater) * (step_temp - prev_temp); |
|
177 double b = SpecificHeatWater * (99 - step_temp); |
|
178 double vol = 0; |
|
179 |
|
180 if (b > 0) |
|
181 vol = round((a / b) * 1000000.0) / 1000000.0; |
|
182 qDebug() << " decoctionVol(" << step_volume << "," << step_temp << "," << prev_temp << "):" << vol; |
|
183 return vol; |
|
184 } |
|
185 |
|
186 |
|
187 void EditRecipe::calcMash() |
|
188 { |
|
189 double infused = 0, vol, a, b, temp; |
|
190 int i, j, n; |
|
191 double lasttemp = 18.0; |
|
192 double graintemp = 18.0; |
|
193 double tuntemp = 18.0; |
|
194 |
|
195 recipe->mashs_time = 0; |
|
196 |
|
197 if (recipe->mashs.size() && recipe->mashs_kg > 0) { |
|
198 qDebug() << "calcMash()"; |
|
199 |
|
200 for (i = 0; i < recipe->mashs.size(); i++) { |
|
201 if (recipe->mashs.at(i).step_type == 0) { // Infusion |
|
202 if (i == 0) { |
|
203 // First mash step, temperature from the mashtun and malt. |
|
204 n = 20; // tun is preheated. |
|
205 tuntemp = recipe->mashs.at(i).step_temp; |
|
206 for (j = 0; j < n; j++) { |
|
207 a = recipe->mashs_kg * graintemp * SpecificHeatMalt + eq_tun_weight * tuntemp * eq_tun_specific_heat; |
|
208 b = recipe->mashs[i].step_temp * |
|
209 (eq_tun_weight * eq_tun_specific_heat + |
|
210 recipe->mashs.at(i).step_infuse_amount * SpecificHeatWater + |
|
211 recipe->mashs_kg * SpecificHeatMalt) - |
|
212 SlakingHeat * recipe->mashs_kg; |
|
213 if (recipe->mashs.at(i).step_infuse_amount > 0) { |
|
214 temp = (b - a) / (recipe->mashs.at(i).step_infuse_amount * SpecificHeatWater); |
|
215 } else { |
|
216 temp = 99; |
|
217 } |
|
218 tuntemp += (temp - tuntemp) / 2; |
|
219 recipe->mashs[i].step_infuse_temp = round(temp * 1000000.0) / 1000000.0; |
|
220 } |
|
221 qDebug() << " init infuse temp:" << recipe->mashs.at(i).step_infuse_temp; |
|
222 } else { |
|
223 // Calculate amount of infusion water. |
|
224 recipe->mashs[i].step_infuse_amount = |
|
225 infusionVol(infused, recipe->mashs_kg, recipe->mashs.at(i).step_infuse_temp, recipe->mashs.at(i).step_temp, lasttemp); |
|
226 qDebug() << i << " vol:" << recipe->mashs.at(i).step_infuse_amount << "temp:" << recipe->mashs.at(i).step_infuse_temp; |
|
227 } |
|
228 infused += recipe->mashs.at(i).step_infuse_amount; |
|
229 } else if (recipe->mashs.at(i).step_type == 1) { // Temperature |
|
230 if (i > 0) |
|
231 recipe->mashs[i].step_infuse_amount = 0; |
|
232 recipe->mashs[i].step_infuse_temp = 0; |
|
233 } else if (recipe->mashs.at(i).step_type == 2) { // Decoction |
|
234 recipe->mashs[i].step_infuse_amount = decoctionVol(infused, recipe->mashs.at(i).step_temp, lasttemp); |
|
235 recipe->mashs[i].step_infuse_temp = 99; |
|
236 } |
|
237 recipe->mashs[i].step_volume = infused; |
|
238 qDebug() << i << " type:" << recipe->mashs.at(i).step_type << "volume:" << recipe->mashs.at(i).step_infuse_amount << "temp:" << recipe->mashs.at(i).step_infuse_temp; |
|
239 lasttemp = recipe->mashs.at(i).step_temp; |
|
240 recipe->mashs_time += recipe->mashs.at(i).step_time; |
|
241 if (i > 0) |
|
242 recipe->mashs_time += recipe->mashs.at(i).ramp_time; |
|
243 recipe->mashs[i].step_wg_ratio = round((infused / recipe->mashs_kg) * 1000000.0) / 1000000.0; |
|
244 } |
|
245 } |
|
246 |
|
247 /* Show the calculated total mash time. */ |
|
248 ui->mash_timeEdit->setText(QString("%1:%2").arg(recipe->mashs_time / 60).arg(recipe->mashs_time % 60, 2, 'f', 0, '0')); |
|
249 } |
|
250 |
|
251 |
162 void EditRecipe::addMashRow_clicked() |
252 void EditRecipe::addMashRow_clicked() |
163 { |
253 { |
164 Mashs newm; |
254 Mashs newm; |
165 |
255 |
166 for (int i = 0; i < recipe->mashs.size(); i++) { |
256 for (int i = 0; i < recipe->mashs.size(); i++) { |
546 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset; |
640 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset; |
547 } else { |
641 } else { |
548 /* |
642 /* |
549 * Got the json data in the steps array, replace the recipe steps. |
643 * Got the json data in the steps array, replace the recipe steps. |
550 */ |
644 */ |
|
645 double infuse = recipe->mashs.at(0).step_infuse_amount; |
551 recipe->mashs.clear(); |
646 recipe->mashs.clear(); |
552 ui->mashsTable->clear(); |
647 ui->mashsTable->clear(); |
553 if (newsteps.isArray()) { |
648 if (newsteps.isArray()) { |
554 for (i = 0; i < newsteps.array().size(); i++) { |
649 for (i = 0; i < newsteps.array().size(); i++) { |
555 QJsonObject obj = newsteps.array().at(i).toObject(); |
650 QJsonObject obj = newsteps.array().at(i).toObject(); |