195 slcdPuts(slcdHandle, text); |
196 slcdPuts(slcdHandle, text); |
196 } |
197 } |
197 |
198 |
198 |
199 |
199 |
200 |
200 void automatic_brew(units_list *, brew_session *); |
201 void automatic_brew(units_list *, brew_session *, a_recipe *, int); |
201 void automatic_brew(units_list *unit, brew_session *brew) |
202 void automatic_brew(units_list *unit, brew_session *brew, a_recipe *recipe, int dosave) |
202 { |
203 { |
|
204 int key, save = dosave; |
|
205 |
|
206 // if (debug) |
|
207 // fprintf(stdout, "auto: step %d\n", brew->brewstep); |
|
208 |
|
209 switch (brew->brewstep) { |
|
210 case STEP_NA: if (debug) |
|
211 fprintf(stdout, "auto: init recipe: %s-%s unit: %s\n", recipe->code, recipe->name, unit->name); |
|
212 syslog(LOG_NOTICE, "AUTO: starting new brew, recipe: %s-%s unit: %s", recipe->code, recipe->name, unit->name); |
|
213 brew->brewstep = STEP_BREWDONE; |
|
214 break; |
|
215 |
|
216 case STEP_BREWINIT: |
|
217 break; |
|
218 case STEP_WATERCHECK: prompt(111, NULL); /* "AUTO --> Mash In " */ |
|
219 prompt(209, NULL); /* " Water Added? " */ |
|
220 break; |
|
221 case STEP_PUMPPRIME: prompt(111, NULL); /* "AUTO --> Mash In " */ |
|
222 prompt(210, NULL); /* " Pump Prime " */ |
|
223 break; |
|
224 case STEP_WAITSTART: prompt(111, NULL); /* "AUTO --> Mash In " */ |
|
225 prompt(212, NULL); /* " To be started in " */ |
|
226 break; |
|
227 case STEP_PREMASH: prompt(111, NULL); /* "AUTO --> Mash In " */ |
|
228 /* Heatup until strike temp reached */ |
|
229 break; |
|
230 case STEP_MASHING: switch (brew->mashstep) { |
|
231 case 0: prompt(111, NULL); |
|
232 break; |
|
233 case 1: prompt(112, NULL); |
|
234 break; |
|
235 case 2: prompt(113, NULL); |
|
236 break; |
|
237 case 3: prompt(114, NULL); |
|
238 break; |
|
239 case 4: prompt(115, NULL); |
|
240 break; |
|
241 case 5: prompt(116, NULL); |
|
242 break; |
|
243 case 6: prompt(117, NULL); |
|
244 break; |
|
245 case 7: prompt(118, NULL); |
|
246 break; |
|
247 } |
|
248 break; |
|
249 case STEP_IODINE: prompt(118, NULL); /* "AUTO --> Mash Out " */ |
|
250 prompt(213, NULL); /* " Iodine test " */ |
|
251 break; |
|
252 case STEP_MASHREMOVE: prompt(118, NULL); /* "AUTO --> Mash Out " */ |
|
253 break; |
|
254 case STEP_PREBOIL: |
|
255 break; |
|
256 case STEP_BOILING: prompt(119, NULL); /* "AUTO --> Boil " */ |
|
257 break; |
|
258 case STEP_BOILDONE: |
|
259 break; |
|
260 case STEP_HOPSTAND1: |
|
261 break; |
|
262 case STEP_COOLING1: prompt(120, NULL); /* "AUTO --> Cooling " */ |
|
263 prompt(214, NULL); /* " START COOLING " */ |
|
264 break; |
|
265 case STEP_WHIRLPOOL1: prompt(121, NULL); /* "AUTO --> Whirlpool " */ |
|
266 break; |
|
267 case STEP_COOLING2: prompt(120, NULL); /* "AUTO --> Cooling " */ |
|
268 break; |
|
269 case STEP_HOPSTAND2: |
|
270 break; |
|
271 case STEP_COOLING3: prompt(120, NULL); /* "AUTO --> Cooling " */ |
|
272 break; |
|
273 case STEP_HOPSTAND3: |
|
274 break; |
|
275 case STEP_COOLING: prompt(120, NULL); /* "AUTO --> Cooling " */ |
|
276 break; |
|
277 case STEP_WHIRLPOOL: prompt(121, NULL); /* "AUTO --> Whirlpool " */ |
|
278 break; |
|
279 case STEP_CLEANUP: |
|
280 break; |
|
281 case STEP_BREWDONE: syslog(LOG_NOTICE, "AUTO: brew done"); |
|
282 brew->brewstep = -1; |
|
283 brew->endtime = time(NULL); |
|
284 prompt(101, NULL); /* " Brewco x.x.x " */ |
|
285 prompt(200, NULL); /* " " */ |
|
286 prompt(301, NULL); /* " Finished " */ |
|
287 prompt(408, NULL); /* "--- --- Ok --- " */ |
|
288 do { |
|
289 key = keywait(); |
|
290 } while (key != KEY_RETURN); |
|
291 /* |
|
292 * Rewrite the display |
|
293 */ |
|
294 prompt(101, NULL); /* " Brewco x.x.x " */ |
|
295 prompt(300, NULL); /* " " */ |
|
296 prompt(401, NULL); /* "--- MAN AUTO SETUP" */ |
|
297 break; |
|
298 } |
|
299 |
|
300 if (save) |
|
301 wrsession(brew); |
203 } |
302 } |
204 |
303 |
205 |
304 |
206 |
305 |
207 void manual_prompt(void) |
306 void manual_prompt(void) |
337 return 0; |
436 return 0; |
338 } |
437 } |
339 |
438 |
340 |
439 |
341 |
440 |
|
441 char *choose_recipe(void); |
|
442 char *choose_recipe(void) |
|
443 { |
|
444 int total, i, key, choice = 1; |
|
445 static char uuid[37]; |
|
446 a_recipe *recipe; |
|
447 char pmpt[81]; |
|
448 |
|
449 strcpy(uuid, (char *)"00000000-0000-0000-0000-000000000000"); |
|
450 for (;;) { |
|
451 total = 0; |
|
452 for (recipe = recipes; recipe; recipe = recipe->next) |
|
453 total++; |
|
454 |
|
455 if (total == 0) |
|
456 return uuid; |
|
457 |
|
458 i = 0; |
|
459 for (recipe = recipes; recipe; recipe = recipe->next) { |
|
460 i++; |
|
461 if (i == choice) |
|
462 break; |
|
463 } |
|
464 |
|
465 prompt(102, NULL); /* " SETUP MENU " */ |
|
466 prompt(221, NULL); /* " Select Recipe " */ |
|
467 if (total) { |
|
468 snprintf(pmpt, Config.lcd_cols + 1, "%s %s ", recipe->code, recipe->name); |
|
469 prompt(300, pmpt); |
|
470 } |
|
471 if (total == 1) |
|
472 prompt(405, NULL); /* "--- --- quit ok " */ |
|
473 else if (choice == 1) |
|
474 prompt(402, NULL); /* "--- dwn quit ok " */ |
|
475 else if (choice == total) |
|
476 prompt(404, NULL); /* " up --- quit ok " */ |
|
477 else |
|
478 prompt(403, NULL); /* " up dwn quit ok " */ |
|
479 |
|
480 key = keywait(); |
|
481 if ((key == KEY_RETURN) || my_shutdown) |
|
482 return uuid; |
|
483 if (key == KEY_ENTER) { |
|
484 strcpy(uuid, recipe->uuid); |
|
485 return uuid; |
|
486 } |
|
487 if ((key == KEY_UP) && (total > 1) && (choice > 1)) { |
|
488 choice--; |
|
489 } |
|
490 if ((key == KEY_DOWN) && (total > 1) && (choice < total)) |
|
491 choice++; |
|
492 } |
|
493 } |
|
494 |
|
495 |
|
496 |
342 int server(void); |
497 int server(void); |
343 int server(void) |
498 int server(void) |
344 { |
499 { |
345 int rc = 0, run = 1, key, temp, MLTp, HLTp, percslot, percfase = PERC_INIT; |
500 int rc = 0, run = 1, dosave, key, temp, MLTp, HLTp, percslot, percfase = PERC_INIT; |
346 int do_init = TRUE, seconds = 0, minutes = 0; |
501 int do_init = TRUE, seconds = 0, minutes = 0; |
347 units_list *unit; |
502 units_list *unit; |
|
503 a_recipe *recipe = NULL; |
348 brew_session *brew = NULL; |
504 brew_session *brew = NULL; |
349 #ifndef HAVE_WIRINGPI_H |
505 #ifndef HAVE_WIRINGPI_H |
350 long t = 0; |
506 long t = 0; |
351 #endif |
507 #endif |
352 time_t now, last = (time_t)0; |
508 time_t now, last = (time_t)0; |
353 long nowmillis, perctimer; |
509 long nowmillis, perctimer; |
|
510 struct tm *tm; |
354 |
511 |
355 prompt(101, NULL); |
512 prompt(101, NULL); |
356 |
513 |
357 /* |
514 /* |
358 * Define special characters in the display CGRAM |
515 * Define special characters in the display CGRAM |
533 |
690 |
534 do_init = FALSE; |
691 do_init = FALSE; |
535 nowmillis = perctimer = millis(); |
692 nowmillis = perctimer = millis(); |
536 percslot = 0; |
693 percslot = 0; |
537 percfase = PERC_INIT; |
694 percfase = PERC_INIT; |
|
695 dosave = 0; |
538 } |
696 } |
539 |
697 |
540 /* run_pause code here */ |
698 /* run_pause code here */ |
541 |
699 |
542 /* |
700 /* |
543 * Update PID's, even if they are off. Both PID's will do |
701 * Update PID's, even if they are off. Both PID's will do |
544 * the scheduling by themselves. |
702 * the scheduling by themselves. |
545 */ |
703 */ |
546 rc = PID_compute(unit->PID_hlt); |
704 rc = PID_compute(unit->PID_hlt); |
547 // if (seconds < 3) |
|
548 // fprintf(stdout, "hlt rc=%d"); |
|
549 rc = PID_compute(unit->PID_mlt); |
705 rc = PID_compute(unit->PID_mlt); |
550 // if (seconds < 3) |
|
551 // fprintf(stdout, " mlt rc=%d\n"); |
|
552 |
706 |
553 /* |
707 /* |
554 * This is the serial heaters schedule loop. The total |
708 * This is the serial heaters schedule loop. The total |
555 * loop time is 5 seconds, heating is 0..100% so we |
709 * loop time is 5 seconds, heating is 0..100% so we |
556 * have 5 mSeconds timeslots. The MLT has priority over |
710 * have 5 mSeconds timeslots. The MLT has priority over |
648 |
804 |
649 if (brew) { |
805 if (brew) { |
650 /* |
806 /* |
651 * Automate mode |
807 * Automate mode |
652 */ |
808 */ |
653 automatic_brew(unit, brew); |
809 automatic_brew(unit, brew, recipe, dosave); |
|
810 dosave = 0; |
|
811 if (brew->brewstep == -1) { |
|
812 /* |
|
813 * Save session and move it |
|
814 */ |
|
815 wrsession(brew); |
|
816 char *fpath, *tpath; |
|
817 fpath = xstrcpy(etcpath); |
|
818 fpath = xstrcat(fpath, (char *)"brewing.xml"); |
|
819 tpath = xstrcpy(varpath); |
|
820 tpath = xstrcat(tpath, (char *)"old/brewing.xml."); |
|
821 mkdirs(tpath, 0755); |
|
822 tpath = xstrcat(tpath, brew->name); |
|
823 if (debug) |
|
824 fprintf(stdout, "auto: saving as %s\n", tpath); |
|
825 file_cp(fpath, tpath); |
|
826 unlink(fpath); |
|
827 free(fpath); |
|
828 free(tpath); |
|
829 |
|
830 /* |
|
831 * Free memory, session is over. |
|
832 */ |
|
833 if (brew->name) |
|
834 free(brew->name); |
|
835 if (brew->uuid_recipe) |
|
836 free(brew->uuid_recipe); |
|
837 if (brew->uuid_unit) |
|
838 free(brew->uuid_unit); |
|
839 free(brew); |
|
840 brew = NULL; |
|
841 } |
654 |
842 |
655 } else if (manual != MANUAL_NONE) { |
843 } else if (manual != MANUAL_NONE) { |
656 /* |
844 /* |
657 * Manual mode |
845 * Manual mode |
658 */ |
846 */ |
673 key = keycheck(); |
861 key = keycheck(); |
674 if (key == KEY_ENTER) { |
862 if (key == KEY_ENTER) { |
675 setup(); |
863 setup(); |
676 prompt(101, NULL); /* " Brewco x.x.x " */ |
864 prompt(101, NULL); /* " Brewco x.x.x " */ |
677 prompt(401, NULL); /* "--- MAN AUTO SETUP" */ |
865 prompt(401, NULL); /* "--- MAN AUTO SETUP" */ |
|
866 } else if (key == KEY_RETURN && ! brew) { |
|
867 int i, isOk = TRUE; |
|
868 char message[41]; |
|
869 |
|
870 tm = localtime(&now); |
|
871 snprintf(message, 40, "%04d%02d%02d-%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); |
|
872 brew = (brew_session *)malloc(sizeof(brew_session)); |
|
873 brew->uuid_recipe = xstrcpy(choose_recipe()); |
|
874 brew->uuid_unit = xstrcpy(unit->uuid); |
|
875 brew->name = xstrcpy(message); |
|
876 brew->brewstep = STEP_NA; |
|
877 brew->mashstep = MASH_NA; |
|
878 brew->timeout = brew->boiltimer = 0; |
|
879 brew->starttime = brew->endtime = (time_t)0; |
|
880 /* |
|
881 * Now check if everything is sane |
|
882 */ |
|
883 if (strcmp(brew->uuid_recipe, (char *)"00000000-0000-0000-0000-000000000000") == 0) { |
|
884 isOk = FALSE; |
|
885 snprintf(message, Config.lcd_cols + 1, " No recipe selected "); |
|
886 if (debug) |
|
887 fprintf(stdout, "brew init: No recipe selected\n"); |
|
888 } |
|
889 if (isOk) { |
|
890 isOk = FALSE; |
|
891 for (recipe = recipes; recipe; recipe = recipe->next) { |
|
892 if (strcmp(recipe->uuid, brew->uuid_recipe) == 0) { |
|
893 isOk = TRUE; |
|
894 if (! recipe->boiltime) |
|
895 isOk = FALSE; |
|
896 for (i = 0; i < 8; i++) { |
|
897 if (! recipe->mash[i].skip && ! recipe->mash[i].setpoint) |
|
898 isOk = FALSE; |
|
899 } |
|
900 for (i = 0; i < 3; i++) { |
|
901 if (! recipe->hopstand[i].skip && recipe->hopstand[i].hold && (recipe->hopstand[i].setpoint == 0)) |
|
902 isOk = FALSE; |
|
903 } |
|
904 break; |
|
905 } |
|
906 } |
|
907 if (isOk == FALSE) { |
|
908 snprintf(message, Config.lcd_cols + 1, " Recipe error "); |
|
909 if (debug) |
|
910 fprintf(stdout, "brew init: recipe error\n"); |
|
911 } |
|
912 } |
|
913 |
|
914 if (debug) |
|
915 fprintf(stdout, "init brew: %s\n", isOk ? (char *)"Ok":(char *)"Error"); |
|
916 |
|
917 if (isOk) { |
|
918 wrsession(brew); |
|
919 } else { |
|
920 prompt(300, message); |
|
921 prompt(408, NULL); /* "--- --- Ok --- " */ |
|
922 key = keywait(); |
|
923 if (brew->name) |
|
924 free(brew->name); |
|
925 if (brew->uuid_recipe) |
|
926 free(brew->uuid_recipe); |
|
927 if (brew->uuid_unit) |
|
928 free(brew->uuid_unit); |
|
929 free(brew); |
|
930 brew = NULL; |
|
931 /* |
|
932 * Rewrite the display |
|
933 */ |
|
934 prompt(101, NULL); /* " Brewco x.x.x " */ |
|
935 prompt(300, NULL); /* " " */ |
|
936 prompt(401, NULL); /* "--- MAN AUTO SETUP" */ |
|
937 } |
|
938 |
678 } else if (key == KEY_DOWN) { |
939 } else if (key == KEY_DOWN) { |
679 manual = MANUAL_SELHLT; |
940 manual = MANUAL_SELHLT; |
680 manual_prompt(); |
941 manual_prompt(); |
681 } |
942 } |
682 } |
943 } |