18 int r_CurrentRec = 1; ///< Current record |
18 int r_CurrentRec = 1; ///< Current record |
19 int r_Records = 1; ///< Total records |
19 int r_Records = 1; ///< Total records |
20 int r_Imported = 0; ///< Total imported |
20 int r_Imported = 0; ///< Total imported |
21 char _xml_element[10][32]; ///< XML element array |
21 char _xml_element[10][32]; ///< XML element array |
22 int _xml_depth; ///< Current depths |
22 int _xml_depth; ///< Current depths |
23 char _xml_add_name[64]; ///< Mash name |
23 char _xml_add_name[64]; ///< Addition name |
24 int _xml_add_type; ///< Mash type |
24 int _xml_add_type; ///< Addition type |
25 int _xml_add_time; ///< Mash rest time |
25 int _xml_add_time; ///< Mash rest time |
26 int _xml_add_ramp; ///< Mash ramp time |
26 int _xml_add_ramp; ///< Mash ramp time |
27 float _xml_add_temp; ///< Mash start temperature |
27 float _xml_add_temp; ///< Mash start temperature |
28 float _xml_add_end; ///< Mash end temperature |
28 float _xml_add_end; ///< Mash end temperature |
29 float _xml_add_amount; ///< Mash infusion amount |
29 float _xml_add_amount; ///< Mash infusion amount |
47 * @param Type The addition type. |
47 * @param Type The addition type. |
48 * @param Time The addition time to add. |
48 * @param Time The addition time to add. |
49 */ |
49 */ |
50 void Addition_Add(char *Name, uint8_t Type, uint16_t Time) |
50 void Addition_Add(char *Name, uint8_t Type, uint16_t Time) |
51 { |
51 { |
|
52 if (Type == ADDITION_HOP_AROMA && Time > 0) { |
|
53 /* |
|
54 * Whirlpool hop. |
|
55 */ |
|
56 recipe.Whirlpool7 = Time; |
|
57 return; |
|
58 } |
|
59 if (Type == ADDITION_HOP_AROMA) |
|
60 Type = ADDITION_HOP_BOIL; /* Flame-out hop, change to boil with zero time. */ |
|
61 |
52 if (! recipe.Additions) { |
62 if (! recipe.Additions) { |
53 // No entries yet, add the first one. |
63 // No entries yet, add the first one. |
54 snprintf(recipe.Addition[recipe.Additions].Name, 63, "%s", Name); |
64 snprintf(recipe.Addition[recipe.Additions].Name, 63, "%s", Name); |
55 recipe.Addition[recipe.Additions].Type = Type; |
65 recipe.Addition[recipe.Additions].Type = Type; |
56 recipe.Addition[recipe.Additions].Time = Time; |
66 recipe.Addition[recipe.Additions].Time = Time; |
70 |
80 |
71 // A new entry and we already have some. Add it and keep the list sorted. |
81 // A new entry and we already have some. Add it and keep the list sorted. |
72 for (int i = 0; i < recipe.Additions; i++) { |
82 for (int i = 0; i < recipe.Additions; i++) { |
73 if (Time > recipe.Addition[i].Time) { |
83 if (Time > recipe.Addition[i].Time) { |
74 // Make room |
84 // Make room |
75 for (int j = i; j < recipe.Additions; j++) { |
85 for (int j = recipe.Additions; j > i; j--) { |
76 sprintf(recipe.Addition[j+1].Name, "%s", recipe.Addition[j].Name); |
86 sprintf(recipe.Addition[j].Name, "%s", recipe.Addition[j-1].Name); |
77 recipe.Addition[j+1].Type = recipe.Addition[j].Type; |
87 recipe.Addition[j].Type = recipe.Addition[j-1].Type; |
78 recipe.Addition[j+1].Time = recipe.Addition[j].Time; |
88 recipe.Addition[j].Time = recipe.Addition[j-1].Time; |
79 } |
89 } |
80 snprintf(recipe.Addition[i].Name, 63, "%s", Name); |
90 snprintf(recipe.Addition[i].Name, 63, "%s", Name); |
81 recipe.Addition[i].Type = Type; |
91 recipe.Addition[i].Type = Type; |
82 recipe.Addition[i].Time = Time; |
92 recipe.Addition[i].Time = Time; |
83 recipe.Additions++; |
93 recipe.Additions++; |
149 recipe.Name[0] = '\0'; |
159 recipe.Name[0] = '\0'; |
150 strncat(recipe.Name, char_data_buffer, 127); |
160 strncat(recipe.Name, char_data_buffer, 127); |
151 } else if ((_xml_depth == 3) && (strcmp("BOIL_TIME", _xml_element[2]) == 0)) { |
161 } else if ((_xml_depth == 3) && (strcmp("BOIL_TIME", _xml_element[2]) == 0)) { |
152 recipe.BoilTime = atoi(char_data_buffer); |
162 recipe.BoilTime = atoi(char_data_buffer); |
153 } else if ((_xml_depth == 3) && (strcmp("BMS_COOLING_TO", _xml_element[2]) == 0)) { |
163 } else if ((_xml_depth == 3) && (strcmp("BMS_COOLING_TO", _xml_element[2]) == 0)) { |
154 recipe.CoolTemp = atoi(char_data_buffer); |
164 recipe.CoolTemp = atof(char_data_buffer); |
155 } else if ((_xml_depth == 5) && (strcmp("HOPS", _xml_element[2]) == 0) && (strcmp("HOP", _xml_element[3]) == 0)) { |
165 } else if ((_xml_depth == 5) && (strcmp("HOPS", _xml_element[2]) == 0) && (strcmp("HOP", _xml_element[3]) == 0)) { |
156 /* |
166 /* |
157 * Hops that are added during the boil. |
167 * Hops that are added during the boil. |
158 * But check for whirlpool hops too. |
168 * But check for "Aroma" hops too. |
159 */ |
169 */ |
160 if (strcmp("NAME", _xml_element[4]) == 0) { |
170 if (strcmp("NAME", _xml_element[4]) == 0) { |
161 _xml_add_name[0] = '\0'; |
171 _xml_add_name[0] = '\0'; |
162 strncat(_xml_add_name, char_data_buffer, 63); |
172 strncat(_xml_add_name, char_data_buffer, 63); |
|
173 _xml_add_time = 0; // reset |
163 } else if (strcmp("USE", _xml_element[4]) == 0) { |
174 } else if (strcmp("USE", _xml_element[4]) == 0) { |
164 _xml_add_valid = (strcmp("Boil", char_data_buffer) == 0); // Only "Boil" is a valid hop |
175 if (strcmp("Boil", char_data_buffer) == 0) { |
165 if (strcmp("Aroma", char_data_buffer) == 0) { |
176 _xml_add_valid = true; |
166 recipe.Whirlpool7 = 30; |
177 _xml_add_type = ADDITION_HOP_BOIL; |
|
178 } else if (strcmp("Aroma", char_data_buffer) == 0) { |
|
179 _xml_add_type = ADDITION_HOP_AROMA; |
|
180 _xml_add_valid = true; |
167 } |
181 } |
168 } else if (strcmp("TIME", _xml_element[4]) == 0) { |
182 } else if (strcmp("TIME", _xml_element[4]) == 0) { |
169 _xml_add_time = atoi(char_data_buffer); |
183 _xml_add_time = atoi(char_data_buffer); |
170 } |
184 } |
171 } else if ((_xml_depth >= 3) && (strcmp("STYLE", _xml_element[2]) == 0)) { |
185 } else if ((_xml_depth >= 3) && (strcmp("STYLE", _xml_element[2]) == 0)) { |
283 { |
297 { |
284 process_char_data_buffer(); |
298 process_char_data_buffer(); |
285 reset_char_data_buffer(); |
299 reset_char_data_buffer(); |
286 if ((_xml_depth == 4) && (strcmp("HOP", _xml_element[3]) == 0)) { |
300 if ((_xml_depth == 4) && (strcmp("HOP", _xml_element[3]) == 0)) { |
287 if (_xml_add_valid) { |
301 if (_xml_add_valid) { |
288 Addition_Add(_xml_add_name, ADDITION_HOP, _xml_add_time); |
302 Addition_Add(_xml_add_name, _xml_add_type, _xml_add_time); |
289 } |
303 } |
290 } |
304 } |
291 if ((_xml_depth == 4) && (strcmp("FERMENTABLE", _xml_element[3]) == 0)) { |
305 if ((_xml_depth == 4) && (strcmp("FERMENTABLE", _xml_element[3]) == 0)) { |
292 if (_xml_add_valid && (_xml_add_type == ADDITION_FERMENTABLE)) { |
306 if (_xml_add_valid && (_xml_add_type == ADDITION_FERMENTABLE)) { |
293 Addition_Add(_xml_add_name, _xml_add_type, _xml_add_time); |
307 Addition_Add(_xml_add_name, _xml_add_type, _xml_add_time); |
309 * Fix problems created by Brewfather and possible others that say that |
323 * Fix problems created by Brewfather and possible others that say that |
310 * the first mash step is a temperature step. It just isn't. |
324 * the first mash step is a temperature step. It just isn't. |
311 */ |
325 */ |
312 if (_xml_add_type == MASHTYPE_TEMPERATURE && recipe.Mashsteps == 0) { |
326 if (_xml_add_type == MASHTYPE_TEMPERATURE && recipe.Mashsteps == 0) { |
313 _xml_add_type = MASHTYPE_INFUSION; |
327 _xml_add_type = MASHTYPE_INFUSION; |
314 // _xml_add_infusion = _xml_add_temp + 1.25; |
|
315 recipe.MashStep[recipe.Mashsteps].Ramp_time = 1; |
328 recipe.MashStep[recipe.Mashsteps].Ramp_time = 1; |
316 } |
329 } |
317 recipe.MashStep[recipe.Mashsteps].Type = _xml_add_type; |
330 recipe.MashStep[recipe.Mashsteps].Type = _xml_add_type; |
318 if (_xml_add_ramp == 0 && recipe.Mashsteps) { |
331 if (_xml_add_ramp == 0 && recipe.Mashsteps) { |
319 recipe.MashStep[recipe.Mashsteps].Ramp_time = (uint16_t)(_xml_add_temp - recipe.MashStep[recipe.Mashsteps - 1].End_temp) + 1; |
332 recipe.MashStep[recipe.Mashsteps].Ramp_time = (uint16_t)(_xml_add_temp - recipe.MashStep[recipe.Mashsteps - 1].End_temp) + 1; |
386 } |
399 } |
387 |
400 |
388 #if 0 |
401 #if 0 |
389 printf("Recipe: %s\n", recipe.Name); |
402 printf("Recipe: %s\n", recipe.Name); |
390 printf("Code : %s\n", recipe.Code); |
403 printf("Code : %s\n", recipe.Code); |
391 printf("Boil time %d minutes\n", recipe.BoilTime); |
404 printf("Boil : %d minutes\n", recipe.BoilTime); |
392 printf("n Stepname T temp end time ramp inft infa\n"); |
405 printf("n Stepname T temp end time ramp inft infa\n"); |
393 printf("- ------------------------------ - ----- ----- ---- ---- ----- -----\n"); |
406 printf("- ------------------------------ - ----- ----- ---- ---- ----- -----\n"); |
394 for (int i = 0; i < 8; i++) { |
407 for (int i = 0; i < recipe.Mashsteps; i++) { |
395 if (recipe.MashStep[i].Step_time) { |
408 printf("%d %-30s %d %5.2f %5.2f %4d %4d %5.2f %5.2f\n", i, recipe.MashStep[i].Name, recipe.MashStep[i].Type, |
396 printf("%d %-30s %d %5.2f %5.2f %4d %4d %5.2f %5.2f\n", i, recipe.MashStep[i].Name, recipe.MashStep[i].Type, |
|
397 recipe.MashStep[i].Step_temp, recipe.MashStep[i].End_temp, |
409 recipe.MashStep[i].Step_temp, recipe.MashStep[i].End_temp, |
398 recipe.MashStep[i].Step_time, recipe.MashStep[i].Ramp_time, |
410 recipe.MashStep[i].Step_time, recipe.MashStep[i].Ramp_time, |
399 recipe.MashStep[i].Infuse_temp, recipe.MashStep[i].Infuse_amount); |
411 recipe.MashStep[i].Infuse_temp, recipe.MashStep[i].Infuse_amount); |
400 } |
412 } |
401 } |
413 printf("\n%d additions\n", recipe.Additions); |
402 printf("%d additions\n", recipe.Additions); |
|
403 printf("n Addition name t Tim\n"); |
414 printf("n Addition name t Tim\n"); |
404 printf("- --------------------------------------------------------------- - ---\n"); |
415 printf("- --------------------------------------------------------------- - ---\n"); |
405 for (int i = 0; i < recipe.Additions; i++) { |
416 for (int i = 0; i < recipe.Additions; i++) { |
406 printf("%d %-63s %d %3d\n", i, recipe.Addition[i].Name, recipe.Addition[i].Type, recipe.Addition[i].Time); |
417 printf("%d %-63s %d %3d\n", i, recipe.Addition[i].Name, recipe.Addition[i].Type, recipe.Addition[i].Time); |
407 } |
418 } |
640 recipe.Mashsteps = 2; |
651 recipe.Mashsteps = 2; |
641 recipe.BoilTime = 60; |
652 recipe.BoilTime = 60; |
642 recipe.Additions = 2; |
653 recipe.Additions = 2; |
643 sprintf(recipe.Addition[0].Name, "Bitterhop"); |
654 sprintf(recipe.Addition[0].Name, "Bitterhop"); |
644 recipe.Addition[0].Time = 60; |
655 recipe.Addition[0].Time = 60; |
645 recipe.Addition[0].Type = ADDITION_HOP; |
656 recipe.Addition[0].Type = ADDITION_HOP_BOIL; |
646 sprintf(recipe.Addition[1].Name, "Aromahop"); |
657 sprintf(recipe.Addition[1].Name, "Aromahop"); |
647 recipe.Addition[1].Time = 10; |
658 recipe.Addition[1].Time = 10; |
648 recipe.Addition[1].Type = ADDITION_HOP; |
659 recipe.Addition[1].Type = ADDITION_HOP_BOIL; |
649 recipe.CoolTemp = 20.0; |
660 recipe.CoolTemp = 20.0; |
650 recipe.Whirlpool9 = 0; |
661 recipe.Whirlpool9 = 0; |
651 recipe.Whirlpool7 = 0; |
662 recipe.Whirlpool7 = 0; |
652 recipe.Whirlpool6 = 0; |
663 recipe.Whirlpool6 = 0; |
653 recipe.Whirlpool2 = 0; |
664 recipe.Whirlpool2 = 0; |
784 if (i == 0) { |
795 if (i == 0) { |
785 EditUint16(tmp, &recipe.Addition[i].Time, 0, recipe.BoilTime); |
796 EditUint16(tmp, &recipe.Addition[i].Time, 0, recipe.BoilTime); |
786 } else { |
797 } else { |
787 EditUint16(tmp, &recipe.Addition[i].Time, 0, recipe.Addition[i-1].Time - 1); |
798 EditUint16(tmp, &recipe.Addition[i].Time, 0, recipe.Addition[i-1].Time - 1); |
788 } |
799 } |
789 recipe.Addition[i].Type = ADDITION_HOP; |
800 recipe.Addition[i].Type = ADDITION_HOP_BOIL; |
790 } |
801 } |
791 } else { |
802 } else { |
792 recipe.Additions = 0; |
803 recipe.Additions = 0; |
793 } |
804 } |
794 |
805 |