brewco/setup.c

changeset 487
d5bc44183aa4
parent 486
5a237a99a793
child 488
bee1f70fb42b
equal deleted inserted replaced
486:5a237a99a793 487:d5bc44183aa4
1 /*****************************************************************************
2 * Copyright (C) 2015
3 *
4 * Michiel Broek <mbroek at mbse dot eu>
5 *
6 * This file is part of the mbsePi-apps
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * mbsePi-apps is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ThermFerm; see the file COPYING. If not, write to the Free
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/
22
23 #include "brewco.h"
24 #include "slcd.h"
25 #include "setup.h"
26 #include "prompt.h"
27 #include "xutil.h"
28 #include "keyboard.h"
29 #include "rdconfig.h"
30 #include "rdrecipes.h"
31
32
33 extern int my_shutdown;
34 extern int debug;
35 extern sys_config Config;
36 extern int lcdHandle;
37 extern int slcdHandle;
38 extern a_recipe *recipes;
39
40
41
42 void editFloat(float *value, float low, float high, char *text)
43 {
44 int key;
45 float new = *value;
46 char pmpt[81];
47
48 prompt(0, NULL);
49 prompt(133, NULL);
50
51 for (;;) {
52 snprintf(pmpt, Config.lcd_cols + 1, "%s: %5.1f\001", text, new);
53 prompt(200, pmpt);
54 if (new == low)
55 prompt(404, NULL);
56 else if (new == high)
57 prompt(402, NULL);
58 else
59 prompt(403, NULL);
60
61 key = keywait();
62 if ((key == KEY_RETURN) || my_shutdown)
63 return;
64 if (key == KEY_UP) {
65 new = new + 0.5;
66 if (new > high)
67 new = high;
68 }
69 if (key == KEY_DOWN) {
70 new = new - 0.5;
71 if (new < low)
72 new = low;
73 }
74 if (key == KEY_ENTER) {
75 *value = new;
76 return;
77 }
78 }
79 }
80
81
82
83 void editDouble(double *value, double low, double high, char *text)
84 {
85 int key;
86 double new = *value;
87 char pmpt[81];
88
89 prompt(0, NULL);
90 prompt(138, NULL);
91
92 for (;;) {
93 snprintf(pmpt, Config.lcd_cols + 1, "%s: %5.2lf", text, new);
94 prompt(200, pmpt);
95 if (new == low)
96 prompt(404, NULL);
97 else if (new == high)
98 prompt(402, NULL);
99 else
100 prompt(403, NULL);
101
102 key = keywait();
103 if ((key == KEY_RETURN) || my_shutdown)
104 return;
105 if (key == KEY_UP) {
106 new = new + 0.5;
107 if (new > high)
108 new = high;
109 }
110 if (key == KEY_DOWN) {
111 new = new - 0.5;
112 if (new < low)
113 new = low;
114 }
115 if (key == KEY_ENTER) {
116 *value = new;
117 return;
118 }
119 }
120 }
121
122
123
124 void editInteger(int *value, int low, int high, int step, char *text, char *text2)
125 {
126 int key, new = *value;
127 char pmpt[81];
128
129 prompt(0, NULL);
130 prompt(134, NULL);
131
132 for (;;) {
133 snprintf(pmpt, Config.lcd_cols + 1, "%s: %3d %s", text, new, text2);
134 prompt(200, pmpt);
135 if (new == low)
136 prompt(404, NULL);
137 else if (new == high)
138 prompt(402, NULL);
139 else
140 prompt(403, NULL);
141
142 key = keywait();
143 if ((key == KEY_RETURN) || my_shutdown)
144 return;
145 if (key == KEY_UP) {
146 new += step;
147 if (new > high)
148 new = high;
149 }
150 if (key == KEY_DOWN) {
151 new -= step;
152 if (new < low)
153 new = low;
154 }
155 if (key == KEY_ENTER) {
156 *value = new;
157 return;
158 }
159 }
160 }
161
162
163
164 void togglePmpts(int *value, char *text, int pno, char *pmpt1, char *pmpt2)
165 {
166 int key, new = *value;
167 char pmpt[81];
168
169 prompt(0, NULL);
170 prompt(pno, NULL);
171
172 for (;;) {
173
174 snprintf(pmpt, Config.lcd_cols + 1, "%s: %s", text, new ? pmpt1:pmpt2);
175 prompt(200, pmpt);
176 if (new) {
177 prompt(404, NULL);
178 } else {
179 prompt(402, NULL);
180 }
181
182 key = keywait();
183 if ((key == KEY_RETURN) || my_shutdown)
184 return;
185 if ((key == KEY_UP) && new)
186 new = 0;
187 else if ((key == KEY_DOWN) && (new == 0))
188 new = 1;
189 if (key == KEY_ENTER) {
190 *value = new;
191 return;
192 }
193 }
194 }
195
196
197
198 void toggleYesNo(int *value, char *text)
199 {
200 togglePmpts(value, text, 132, (char *)"Yes", (char *)"No ");
201 }
202
203
204
205 void toggleDirection(int *value, char *text)
206 {
207 togglePmpts(value, text, 137, (char *)"Reverse", (char *)"Direct ");
208 }
209
210
211
212 void editName(char *name, char *text)
213 {
214 char pmpt[81];
215 int i, x = 0, key, val;
216
217 if (debug)
218 fprintf(stdout, "editName(%s)\n", name);
219
220 prompt(0, NULL);
221 prompt(131, NULL); /* " Change Name " */
222 prompt(417, NULL); /* " up dwn next ok " */
223
224 for (;;) {
225 snprintf(pmpt, Config.lcd_cols + 1, " ");
226 prompt(200, pmpt);
227 #ifdef HAVE_WIRINGPI_H
228 lcdPosition(lcdHandle, x, 1);
229 lcdPutchar(lcdHandle, '*');
230 #endif
231 slcdPosition(slcdHandle, x, 1);
232 slcdPutchar(slcdHandle, '*');
233 snprintf(pmpt, Config.lcd_cols + 1, "%s", name);
234 prompt(300, pmpt);
235
236 key = keywait();
237
238 if ((key == KEY_ENTER) || my_shutdown) {
239 if (debug)
240 fprintf(stdout, "End editName(%s)\n", name);
241 for (i = strlen(name) -1; i > 1; i--) {
242 if (name[i] != ' ')
243 break;
244 name[i] = '\0';
245 }
246 if (debug)
247 fprintf(stdout, "End editName(%s)\n", name);
248 return;
249 }
250 if (key == KEY_RETURN) {
251 if (x < 19)
252 x++;
253 else
254 x = 0;
255 if (debug)
256 fprintf(stdout, "editName: strlen=%d x=%d\n", (int)strlen(name) - 1, x);
257 if (x > ((int)strlen(name) - 1)) {
258 name[x + 1] = '\0';
259 name[x] = ' ';
260 }
261 }
262 if (key == KEY_UP || key == KEY_DOWN) {
263 val = name[x];
264 if ((key == KEY_UP) && (val < 126))
265 val++;
266 if ((key == KEY_DOWN) && (val > 32))
267 val--;
268 name[x] = val;
269 }
270 }
271 }
272
273
274
275 void editPID(pid_var *pid)
276 {
277 int idx = 1, key, val;
278 char pmpt[81];
279 double Kp, Ki, Kd;
280
281 if (debug)
282 fprintf(stdout, "editPID()\n");
283
284 for (;;) {
285 prompt(0, NULL);
286 prompt(192, NULL);
287
288 if (idx == 1)
289 prompt(402, NULL);
290 else if (idx == 5)
291 prompt(404, NULL);
292 else
293 prompt(403, NULL);
294
295 switch (idx) {
296 case 1: snprintf(pmpt, Config.lcd_cols + 1, "PID Kp: %5.2f", PID_getKp(pid));
297 break;
298 case 2: snprintf(pmpt, Config.lcd_cols + 1, "PID Ki: %5.2f", PID_getKi(pid));
299 break;
300 case 3: snprintf(pmpt, Config.lcd_cols + 1, "PID Kd: %5.2f", PID_getKd(pid));
301 break;
302 case 4: snprintf(pmpt, Config.lcd_cols + 1, "SampleTime: %3d mSec", PID_getSampleTime(pid));
303 break;
304 case 5: snprintf(pmpt, Config.lcd_cols + 1, "Direction: %s", PID_getDirection(pid) ? (char *)"Reverse" : (char *)"Direct");
305 break;
306 }
307 prompt(200, pmpt);
308
309 key = keywait();
310 if ((key == KEY_RETURN) || my_shutdown) {
311 if (debug)
312 fprintf(stdout, "End editPID\n");
313 return;
314 }
315
316 if ((key == KEY_UP) && (idx > 1))
317 idx--;
318 if ((key == KEY_DOWN) && (idx < 5))
319 idx++;
320
321 if (key == KEY_ENTER) {
322
323 Kp = PID_getKp(pid);
324 Ki = PID_getKi(pid);
325 Kd = PID_getKd(pid);
326
327 switch(idx) {
328 case 1: editDouble(&Kp, 0.5, 50, (char *)"PID Kp");
329 PID_setTunings(pid, Kp, Ki, Kd);
330 break;
331 case 2: editDouble(&Ki, 0.5, 50, (char *)"PID Ki");
332 PID_setTunings(pid, Kp, Ki, Kd);
333 break;
334 case 3: editDouble(&Kd, 0.5, 50, (char *)"PID Kd");
335 PID_setTunings(pid, Kp, Ki, Kd);
336 break;
337 case 4: val = PID_getSampleTime(pid);
338 editInteger(&val, 50, 500, 10, (char *)"SampleTime", (char *)"mSec");
339 PID_setSampleTime(pid, val);
340 break;
341 case 5: val = PID_getDirection(pid);
342 toggleDirection(&val, (char *)"Direction");
343 PID_setDirection(pid, val);
344 break;
345 }
346 }
347 }
348 }
349
350
351
352 void editMash(mash_step *mash)
353 {
354 int key, idx = 1, lo, hi;
355 char pmpt[81];
356
357 for (;;) {
358 prompt(0, NULL);
359 prompt(194, NULL);
360
361 if (mash->canskip) {
362 lo = 1;
363 if (mash->skip)
364 hi = 1;
365 else
366 hi = 3;
367 } else {
368 lo = 2;
369 hi = 3;
370 }
371 if (idx < lo)
372 idx = lo;
373 if (idx > hi)
374 idx = hi;
375 if (debug)
376 fprintf(stdout, "editMash canskip=%d skip=%d lo=%d hi=%d idx=%d\n", mash->canskip, mash->skip, lo, hi, idx);
377
378 switch (idx) {
379 case 1: snprintf(pmpt, Config.lcd_cols + 1, " Mashstep skip: %s", mash->skip ? (char *)"Yes":(char *)"No");
380 break;
381 case 2: snprintf(pmpt, Config.lcd_cols + 1, " Setpoint: %5.1f\001", mash->setpoint);
382 break;
383 case 3: snprintf(pmpt, Config.lcd_cols + 1, " Duration: %3d mins", mash->duration);
384 break;
385 }
386 prompt(200, pmpt);
387
388 if (lo == hi)
389 prompt(405, NULL); /* "--- --- quit ok " */
390 else if (idx == lo)
391 prompt(402, NULL); /* "--- dwn quit ok " */
392 else if (idx == hi)
393 prompt(404, NULL); /* " up --- quit ok " */
394 else
395 prompt(403, NULL); /* " up dwn quit ok " */
396
397 key = keywait();
398 if ((key == KEY_RETURN) || my_shutdown)
399 return;
400 if ((key == KEY_UP) && (idx > lo))
401 idx--;
402 if ((key == KEY_DOWN) && (idx < hi))
403 idx++;
404 if (key == KEY_ENTER) {
405 switch(idx) {
406 case 1: toggleYesNo(&mash->skip, (char *)" Mashstep skip");
407 break;
408 case 2: editFloat(&mash->setpoint, mash->min, mash->max, (char *)" Setpoint");
409 break;
410 case 3: editInteger(&mash->duration, 1, 120, 1, (char *)" Duration", (char *)"mins");
411 break;
412 }
413 }
414 }
415 }
416
417
418
419 void editHopaddition(hop_addition *hops, int boiltime)
420 {
421 int key, idx = 1, hi;
422 char pmpt[81];
423
424 for (;;) {
425 prompt(0, NULL);
426 prompt(195, NULL);
427
428 if (hops->skip)
429 hi = 1;
430 else
431 hi = 2;
432 if (idx > hi)
433 idx = hi;
434 if (debug)
435 fprintf(stdout, "editHopaddition skip=%d hi=%d idx=%d\n", hops->skip, hi, idx);
436
437 switch (idx) {
438 case 1: snprintf(pmpt, Config.lcd_cols + 1, "Addition skip: %s", hops->skip ? (char *)"Yes":(char *)"No");
439 break;
440 case 2: snprintf(pmpt, Config.lcd_cols + 1, " Boil for: %3d mins", hops->boiltime);
441 break;
442 }
443 prompt(200, pmpt);
444
445 if (hi == 1)
446 prompt(405, NULL); /* "--- --- quit ok " */
447 else if (idx == 1)
448 prompt(402, NULL); /* "--- dwn quit ok " */
449 else if (idx == hi)
450 prompt(404, NULL); /* " up --- quit ok " */
451 else
452 prompt(403, NULL); /* " up dwn quit ok " */
453
454 key = keywait();
455 if ((key == KEY_RETURN) || my_shutdown)
456 return;
457 if ((key == KEY_UP) && (idx > 1))
458 idx--;
459 if ((key == KEY_DOWN) && (idx < hi))
460 idx++;
461 if (key == KEY_ENTER) {
462 switch (idx) {
463 case 1: toggleYesNo(&hops->skip, (char *)"Addition skip");
464 break;
465 case 2: editInteger(&hops->boiltime, -1, boiltime, 1, (char *)" Boil for", (char *)"mins");
466 break;
467 }
468 }
469 }
470 }
471
472
473
474 void editHopstand(hop_stand *hops)
475 {
476 int key, idx = 1, hi;
477 char pmpt[81];
478
479 for (;;) {
480 prompt(0, NULL);
481 prompt(196, NULL);
482
483 if (hops->skip)
484 hi = 1;
485 else
486 hi = 4;
487 if (idx < 1)
488 idx = 1;
489 if (idx > hi)
490 idx = hi;
491 if (debug)
492 fprintf(stdout, "editHopstand skip=%d hi=%d idx=%d\n", hops->skip, hi, idx);
493
494 switch (idx) {
495 case 1: snprintf(pmpt, Config.lcd_cols + 1, "Hopstand skip: %s", hops->skip ? (char *)"Yes":(char *)"No");
496 break;
497 case 2: snprintf(pmpt, Config.lcd_cols + 1, "Hold temperature: %s", hops->hold ? (char *)"Yes":(char *)"No");
498 break;
499 case 3: snprintf(pmpt, Config.lcd_cols + 1, " Setpoint: %5.1f\001", hops->setpoint);
500 break;
501 case 4: snprintf(pmpt, Config.lcd_cols + 1, " Duration: %3d mins", hops->duration);
502 break;
503 }
504 prompt(200, pmpt);
505
506 if (hi == 1)
507 prompt(405, NULL); /* "--- --- quit ok " */
508 else if (idx == 1)
509 prompt(402, NULL); /* "--- dwn quit ok " */
510 else if (idx == hi)
511 prompt(404, NULL); /* " up --- quit ok " */
512 else
513 prompt(403, NULL); /* " up dwn quit ok " */
514
515 key = keywait();
516 if ((key == KEY_RETURN) || my_shutdown)
517 return;
518 if ((key == KEY_UP) && (idx > 1))
519 idx--;
520 if ((key == KEY_DOWN) && (idx < hi))
521 idx++;
522 if (key == KEY_ENTER) {
523 switch(idx) {
524 case 1: toggleYesNo(&hops->skip, (char *)"Hopstand skip");
525 break;
526 case 2: toggleYesNo(&hops->hold, (char *)"Hold temperature");
527 break;
528 case 3: editFloat(&hops->setpoint, hops->min, hops->max, (char *)" Setpoint");
529 break;
530 case 4: editInteger(&hops->duration, 10, 240, 10, (char *)" Duration", (char *)"mins");
531 break;
532 }
533 }
534 }
535 }
536
537
538
539 void editSensor(char *uuid, char *text)
540 {
541 char pmpt[81];
542 int i, old, choices, idx = 1, key;
543 devices_list *device;
544
545 if (debug)
546 fprintf(stdout, "editSensor(%s, %s)\n", uuid, text);
547
548 old = 1; // 1d0e5bb8-7408-48b9-abb4-e9041d7b99fe
549 if ((i = strcmp((char *)"00000000-0000-0000-0000-000000000000", uuid))) {
550 for (device = Config.devices; device; device = device->next) {
551 if (device->direction == DEVDIR_IN_ANALOG) {
552 old++;
553 if (strcmp(device->uuid, uuid) == 0)
554 break;
555 }
556 }
557 }
558
559 if (debug)
560 fprintf(stdout, "editSensor(%s) old sensor index=%d\n", text, old);
561
562 for (;;) {
563 prompt(0, NULL);
564 snprintf(pmpt, Config.lcd_cols + 1, "Edit %s", text);
565 prompt(100, pmpt);
566
567 /*
568 * Count valid sensors
569 */
570 choices = 1;
571 if (old == 1) {
572 snprintf(pmpt, Config.lcd_cols + 1, "N/A");
573 }
574 for (device = Config.devices; device; device = device->next) {
575 if (device->direction == DEVDIR_IN_ANALOG) {
576 choices++;
577 if (choices == old) {
578 snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description);
579 }
580 }
581 }
582 prompt(200, pmpt); /* Display current sensor */
583 i = 1;
584 if (idx == 1) {
585 snprintf(pmpt, Config.lcd_cols + 1, "N/A");
586 } else {
587 for (device = Config.devices; device; device = device->next) {
588 if (device->direction == DEVDIR_IN_ANALOG) {
589 i++;
590 if (i == idx) {
591 snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description);
592 }
593 }
594 }
595 }
596 prompt(300, pmpt); /* Display possible new sensor */
597
598
599 if (choices == 1)
600 prompt(405, NULL);
601 else if (idx == 1)
602 prompt(402, NULL);
603 else if (idx == choices)
604 prompt(404, NULL);
605 else
606 prompt(403, NULL);
607
608 key = keywait();
609 if ((key == KEY_RETURN) || my_shutdown) {
610 if (debug)
611 fprintf(stdout, "End editSensor\n");
612 return;
613 }
614
615 if ((key == KEY_UP) && (idx > 1))
616 idx--;
617 if ((key == KEY_DOWN) && (idx < choices))
618 idx++;
619
620 if ((key == KEY_ENTER) && (idx != old)) {
621 /*
622 * Select new sensor.
623 */
624 if (idx == 1) {
625 /*
626 * Disable the sensor
627 */
628 strncpy(uuid, (char *)"00000000-0000-0000-0000-000000000000", 36);
629 old = idx;
630 } else {
631 i = 1;
632 for (device = Config.devices; device; device = device->next) {
633 if (device->direction == DEVDIR_IN_ANALOG) {
634 i++;
635 if (i == idx) {
636 strncpy(uuid, device->uuid, 36);
637 break;
638 }
639 }
640 }
641 old = idx;
642 }
643 }
644 }
645 }
646
647
648
649 void editRelay(char *uuid, char *text)
650 {
651 char pmpt[81];
652 int i, old, choices, idx = 1, key;
653 devices_list *device;
654
655 if (debug)
656 fprintf(stdout, "editRelay(%s, %s)\n", uuid, text);
657
658 old = 1; // 1d0e5bb8-7408-48b9-abb4-e9041d7b99fe
659 if ((i = strcmp((char *)"00000000-0000-0000-0000-000000000000", uuid))) {
660 for (device = Config.devices; device; device = device->next) {
661 if (device->direction == DEVDIR_OUT_ANALOG) {
662 old++;
663 if (strcmp(device->uuid, uuid) == 0)
664 break;
665 }
666 }
667 }
668
669 if (debug)
670 fprintf(stdout, "editRelay(%s) old sensor index=%d\n", text, old);
671
672 for (;;) {
673 prompt(0, NULL);
674 snprintf(pmpt, Config.lcd_cols + 1, "Edit %s", text);
675 prompt(100, pmpt);
676
677 /*
678 * Count valid sensors
679 */
680 choices = 1;
681 if (old == 1) {
682 snprintf(pmpt, Config.lcd_cols + 1, "N/A");
683 }
684 for (device = Config.devices; device; device = device->next) {
685 if (device->direction == DEVDIR_OUT_ANALOG) {
686 choices++;
687 if (choices == old) {
688 snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description);
689 }
690 }
691 }
692 prompt(200, pmpt); /* Display current relay */
693 i = 1;
694 if (idx == 1) {
695 snprintf(pmpt, Config.lcd_cols + 1, "N/A");
696 } else {
697 for (device = Config.devices; device; device = device->next) {
698 if (device->direction == DEVDIR_OUT_ANALOG) {
699 i++;
700 if (i == idx) {
701 snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description);
702 }
703 }
704 }
705 }
706 prompt(300, pmpt); /* Display possible new relay */
707
708 if (choices == 1)
709 prompt(405, NULL);
710 else if (idx == 1)
711 prompt(402, NULL);
712 else if (idx == choices)
713 prompt(404, NULL);
714 else
715 prompt(403, NULL);
716
717 key = keywait();
718 if ((key == KEY_RETURN) || my_shutdown) {
719 if (debug)
720 fprintf(stdout, "End editRelay\n");
721 return;
722 }
723
724 if ((key == KEY_UP) && (idx > 1))
725 idx--;
726 if ((key == KEY_DOWN) && (idx < choices))
727 idx++;
728
729 if ((key == KEY_ENTER) && (idx != old)) {
730 /*
731 * Select new output.
732 */
733 if (idx == 1) {
734 /*
735 * Disable the output
736 */
737 strncpy(uuid, (char *)"00000000-0000-0000-0000-000000000000", 36);
738 old = idx;
739 } else {
740 i = 1;
741 for (device = Config.devices; device; device = device->next) {
742 if (device->direction == DEVDIR_OUT_ANALOG) {
743 i++;
744 if (i == idx) {
745 strncpy(uuid, device->uuid, 36);
746 break;
747 }
748 }
749 }
750 old = idx;
751 }
752 }
753 }
754 }
755
756
757
758 /*
759 * Edit a single unit
760 */
761 void editUnit(units_list *unit)
762 {
763 int idx = 1, key;
764 char pmpt[81], *uuid, *name;
765 uLong ocrc, ncrc;
766
767 if (debug)
768 fprintf(stdout, "Start edit brewsystem %d %s\n", unit->number, unit->uuid);
769
770 prompt(0, NULL);
771 ncrc = ocrc = crc32(0L, Z_NULL, 0);
772 ocrc = crc32(ocrc, (const Bytef *) unit, sizeof(units_list));
773
774 for (;;) {
775
776 prompt(0, NULL);
777 prompt(193, NULL);
778
779 if (idx == 1)
780 prompt(402, NULL);
781 else if (idx == 21)
782 prompt(404, NULL);
783 else
784 prompt(403, NULL);
785
786 switch (idx) { // 12345678901234567890
787 case 1: snprintf(pmpt, Config.lcd_cols + 1, "Unit name:");
788 prompt(200, pmpt);
789 snprintf(pmpt, Config.lcd_cols + 1, "%s", unit->name);
790 prompt(300, pmpt);
791 break;
792 case 2: snprintf(pmpt, Config.lcd_cols + 1, " HLT sensor setup");
793 prompt(200, pmpt);
794 break;
795 case 3: snprintf(pmpt, Config.lcd_cols + 1, " HLT heater setup");
796 prompt(200, pmpt);
797 break;
798 case 4: snprintf(pmpt, Config.lcd_cols + 1, " MLT sensor setup");
799 prompt(200, pmpt);
800 break;
801 case 5: snprintf(pmpt, Config.lcd_cols + 1, " MLT heater setup");
802 prompt(200, pmpt);
803 break;
804 case 6: snprintf(pmpt, Config.lcd_cols + 1, " MLT pump setup");
805 prompt(200, pmpt);
806 break;
807 case 7: snprintf(pmpt, Config.lcd_cols + 1, "MLT heat b4 HLT: %s", unit->hlt_heater_mltfirst ? (char *)"Yes":(char *)"No");
808 prompt(200, pmpt);
809 break;
810 case 8: snprintf(pmpt, Config.lcd_cols + 1, "Pump cycle: %3d mins", unit->pump_cycle);
811 prompt(200, pmpt);
812 break;
813 case 9: snprintf(pmpt, Config.lcd_cols + 1, "Pump rest : %3d mins", unit->pump_rest);
814 prompt(200, pmpt);
815 break;
816 case 10: snprintf(pmpt, Config.lcd_cols + 1, " Pump pre-mash: %s", unit->pump_premash ? (char *)"Yes":(char *)"No");
817 prompt(200, pmpt);
818 break;
819 case 11: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-mash: %s", unit->pump_onmash ? (char *)"Yes":(char *)"No");
820 prompt(200, pmpt);
821 break;
822 case 12: snprintf(pmpt, Config.lcd_cols + 1, " Pump mashout: %s", unit->pump_mashout ? (char *)"Yes":(char *)"No");
823 prompt(200, pmpt);
824 break;
825 case 13: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-boil: %s", unit->pump_onboil ? (char *)"Yes":(char *)"No");
826 prompt(200, pmpt);
827 break;
828 case 14: snprintf(pmpt, Config.lcd_cols + 1, " Pump stop: %5.1f\001", unit->pump_stop);
829 prompt(200, pmpt);
830 break;
831 case 15: snprintf(pmpt, Config.lcd_cols + 1, " Skip Add: %s", unit->skip_add ? (char *)"Yes":(char *)"No");
832 prompt(200, pmpt);
833 break;
834 case 16: snprintf(pmpt, Config.lcd_cols + 1, " Skip Remove: %s", unit->skip_remove ? (char *)"Yes":(char *)"No");
835 prompt(200, pmpt);
836 break;
837 case 17: snprintf(pmpt, Config.lcd_cols + 1, " Skip Iodine: %s", unit->skip_iodine ? (char *)"Yes":(char *)"No");
838 prompt(200, pmpt);
839 break;
840 case 18: snprintf(pmpt, Config.lcd_cols + 1, "Iodine time: %3d min", unit->iodine_time);
841 prompt(200, pmpt);
842 break;
843 case 19: snprintf(pmpt, Config.lcd_cols + 1, " Whirlpool: %s", unit->whirlpool ? (char *)"Yes":(char *)"No");
844 prompt(200, pmpt);
845 break;
846 case 20: snprintf(pmpt, Config.lcd_cols + 1, " HLT PID setup");
847 prompt(200, pmpt);
848 break;
849 case 21: snprintf(pmpt, Config.lcd_cols + 1, " MLT PID setup");
850 prompt(200, pmpt);
851 break;
852 }
853
854 key = keywait();
855 if ((key == KEY_RETURN) || my_shutdown) {
856 ncrc = crc32(ncrc, (const Bytef *)unit, sizeof(units_list));
857 if (ocrc != ncrc)
858 wrconfig();
859 if (debug)
860 fprintf(stdout, "End edit brewsystem %d %s\n", unit->number, unit->uuid);
861 return;
862 }
863
864 if ((key == KEY_UP) && (idx > 1))
865 idx--;
866 if ((key == KEY_DOWN) && (idx < 21))
867 idx++;
868
869 if (key == KEY_ENTER) {
870 switch(idx) {
871 case 1: name = calloc(sizeof(char), 21);
872 snprintf(name, 21, unit->name);
873 editName(name, (char *)"Unit name");
874 if (unit->name)
875 free(unit->name);
876 unit->name = xstrcpy(name);
877 free(name);
878 break;
879 case 2: uuid = xstrcpy(unit->hlt_sensor.uuid);
880 editSensor(uuid, (char *)"HLT sensor");
881 strncpy(unit->hlt_sensor.uuid, uuid, 36);
882 free(uuid);
883 break;
884 case 3: uuid = xstrcpy(unit->hlt_heater.uuid);
885 editRelay(uuid, (char *)"HLT heater");
886 strncpy(unit->hlt_heater.uuid, uuid, 36);
887 free(uuid);
888 break;
889 case 4: uuid = xstrcpy(unit->mlt_sensor.uuid);
890 editSensor(uuid, (char *)"MLT sensor");
891 strncpy(unit->mlt_sensor.uuid, uuid, 36);
892 free(uuid);
893 break;
894 case 5: uuid = xstrcpy(unit->mlt_heater.uuid);
895 editRelay(uuid, (char *)"MLT heater");
896 strncpy(unit->mlt_heater.uuid, uuid, 36);
897 free(uuid);
898 break;
899 case 6: uuid = xstrcpy(unit->mlt_pump.uuid);
900 editRelay(uuid, (char *)"MLT pump");
901 strncpy(unit->mlt_pump.uuid, uuid, 36);
902 free(uuid);
903 break;
904 case 7: toggleYesNo(&unit->hlt_heater_mltfirst, (char *)"MLT heat b4 HLT");
905 break;
906 case 8: editInteger(&unit->pump_cycle, 5, 15, 1, (char *)"Pump cycle", (char *)"mins");
907 break;
908 case 9: editInteger(&unit->pump_rest, 1, 5, 1, (char *)"Pump rest ", (char *)"mins");
909 break;
910 case 10: toggleYesNo(&unit->pump_premash, (char *)" Pump pre-mash");
911 break;
912 case 11: toggleYesNo(&unit->pump_onmash, (char *)" Pump on-mash");
913 break;
914 case 12: toggleYesNo(&unit->pump_mashout, (char *)" Pump mashout");
915 break;
916 case 13: toggleYesNo(&unit->pump_onboil, (char *)" Pump on-boil");
917 break;
918 case 14: editFloat(&unit->pump_stop, 80.0, 110.0, (char *)" Pump stop");
919 break;
920 case 15: toggleYesNo(&unit->skip_add, (char *)"Skip add water");
921 break;
922 case 16: toggleYesNo(&unit->skip_remove, (char *)"Skip remove Mash");
923 break;
924 case 17: toggleYesNo(&unit->skip_iodine, (char *)"Skip iodine test");
925 break;
926 case 18: editInteger(&unit->iodine_time, 10, 240, 10, (char *)"Iodine time", (char *)"min");
927 break;
928 case 19: toggleYesNo(&unit->whirlpool, (char *)"Do a whirlpool");
929 break;
930 case 20: editPID(unit->PID_hlt);
931 break;
932 case 21: editPID(unit->PID_mlt);
933 break;
934 }
935 }
936 }
937 }
938
939
940
941 void addUnit(int number)
942 {
943 units_list *tmpu, *unit = (units_list *)malloc(sizeof(units_list));
944 char name[81];
945 uuid_t uu;
946 double Input, Output, Setpoint;
947
948 if (debug)
949 fprintf(stdout, "Adding new brewsystem %d\n", number);
950 unit->next = NULL;
951 unit->version = 1;
952 unit->uuid = malloc(37);
953 uuid_generate(uu);
954 uuid_unparse(uu, unit->uuid);
955 snprintf(name, 20, "System %d", number);
956 unit->name = xstrcpy(name);
957 unit->number = number;
958 if (number == 1)
959 unit->active = 1;
960 else
961 unit->active = 0;
962 unit->hlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
963 unit->hlt_sensor.state = DEVPRESENT_UNDEF;
964 unit->hlt_sensor.value = 0;
965 unit->mlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
966 unit->mlt_sensor.state = DEVPRESENT_UNDEF;
967 unit->mlt_sensor.value = 0;
968 unit->hlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
969 unit->hlt_heater.value = 0;
970 unit->hlt_heater.delay = 0;
971 unit->mlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
972 unit->mlt_heater.value = 0;
973 unit->mlt_heater.delay = 0;
974 unit->mlt_pump.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
975 unit->mlt_pump.value = 0;
976 unit->mlt_pump.delay = 0;
977 unit->hlt_heater_mltfirst = 1;
978 unit->pump_cycle = 7;
979 unit->pump_rest = 2;
980 unit->pump_premash = 1;
981 unit->pump_onmash = 1;
982 unit->pump_mashout = 0;
983 unit->pump_onboil = 0;
984 unit->pump_stop = 90;
985 unit->skip_add = 0;
986 unit->skip_remove = 0;
987 unit->skip_iodine = 0;
988 unit->iodine_time = 90;
989 unit->whirlpool = 1;
990 unit->PID_hlt = (pid_var *)malloc(sizeof(pid_var));
991 unit->PID_mlt = (pid_var *)malloc(sizeof(pid_var));
992 Input = Setpoint = 20.0;
993 Output = 0;
994 PID_init(unit->PID_hlt, &Input, &Output, &Setpoint, 2, 5, 1, P_DIRECT);
995 PID_init(unit->PID_mlt, &Input, &Output, &Setpoint, 2, 5, 1, P_DIRECT);
996
997 editUnit(unit);
998
999 if (Config.units == NULL) {
1000 Config.units = unit;
1001 } else {
1002 for (tmpu = Config.units; tmpu; tmpu = tmpu->next) {
1003 if (tmpu->next == NULL) {
1004 tmpu->next = unit;
1005 break;
1006 }
1007 }
1008 }
1009 syslog(LOG_NOTICE, "Brewsystem %d added to the configuration", number);
1010 if (debug)
1011 fprintf(stdout, "Brewsystem %d added to the configuration\n", number);
1012 }
1013
1014
1015
1016 /*
1017 * Edit a single recipe
1018 */
1019 void editRecipe(a_recipe *recipe)
1020 {
1021 int idx = 1, i, key;
1022 char pmpt[81], *name;
1023 uLong ocrc, ncrc;
1024
1025 if (debug)
1026 fprintf(stdout, "Start edit recipe `%s' %s\n", recipe->name, recipe->uuid);
1027
1028 prompt(0, NULL);
1029 ncrc = ocrc = crc32(0L, Z_NULL, 0);
1030 ocrc = crc32(ocrc, (const Bytef *) recipe, sizeof(a_recipe));
1031
1032 for (;;) {
1033
1034 prompt(0, NULL);
1035 prompt(191, NULL); /* " Edit recipe " */
1036
1037 if (idx == 1)
1038 prompt(402, NULL); /* "--- dwn quit ok " */
1039 else if (idx == 24)
1040 prompt(404, NULL); /* " up --- quit ok " */
1041 else
1042 prompt(403, NULL); /* " up dwn quit ok " */
1043
1044 switch (idx) { // 12345678901234567890
1045 case 1: snprintf(pmpt, Config.lcd_cols + 1, "Recipe name:");
1046 prompt(200, pmpt);
1047 snprintf(pmpt, Config.lcd_cols + 1, "%s", recipe->name);
1048 prompt(300, pmpt);
1049 break;
1050 case 2: snprintf(pmpt, Config.lcd_cols + 1, "Recipe code:");
1051 prompt(200, pmpt);
1052 snprintf(pmpt, Config.lcd_cols + 1, "%s", recipe->code);
1053 prompt(300, pmpt);
1054 break;
1055 case 3: snprintf(pmpt, Config.lcd_cols + 1, "Boil time: %3d mins", recipe->boiltime);
1056 prompt(200, pmpt);
1057 break;
1058 case 4: snprintf(pmpt, Config.lcd_cols + 1, " Cool to: %5.1f\001", recipe->coolto);
1059 prompt(200, pmpt);
1060 break;
1061 case 5:
1062 case 6:
1063 case 7:
1064 case 8:
1065 case 9:
1066 case 10:
1067 case 11:
1068 case 12: snprintf(pmpt, Config.lcd_cols + 1, "Mash: %s", recipe->mash[idx - 5].name);
1069 prompt(200, pmpt);
1070 if (recipe->mash[idx - 5].skip)
1071 snprintf(pmpt, Config.lcd_cols + 1, " Skipped");
1072 else
1073 snprintf(pmpt, Config.lcd_cols + 1, " Sv %4.1f\001 %3d mins", recipe->mash[idx - 5].setpoint, recipe->mash[idx - 5].duration);
1074 prompt(300, pmpt);
1075 break;
1076 case 13:
1077 case 14:
1078 case 15:
1079 case 16:
1080 case 17:
1081 case 18:
1082 case 19:
1083 case 20:
1084 case 21:
1085 case 22: snprintf(pmpt, Config.lcd_cols + 1, "Add: %s", recipe->hops[idx - 13].name);
1086 prompt(200, pmpt);
1087 if (recipe->hops[idx - 13].skip)
1088 snprintf(pmpt, Config.lcd_cols + 1, " Skipped");
1089 else {
1090 if (recipe->hops[idx - 13].boiltime == -1)
1091 snprintf(pmpt, Config.lcd_cols + 1, " First Wort Hop");
1092 else
1093 snprintf(pmpt, Config.lcd_cols + 1, " Boil for %3d mins", recipe->hops[idx - 13].boiltime);
1094 }
1095 prompt(300, pmpt);
1096 break;
1097 case 23:
1098 case 24:
1099 case 25: snprintf(pmpt, Config.lcd_cols + 1, "Hopstand: %s", recipe->hopstand[idx - 23].name);
1100 prompt(200, pmpt);
1101 if (recipe->hopstand[idx - 23].skip)
1102 snprintf(pmpt, Config.lcd_cols + 1, " Skipped");
1103 else if (recipe->hopstand[idx - 23].hold)
1104 snprintf(pmpt, Config.lcd_cols + 1, "Hold at %4.1f %3d mins", recipe->hopstand[idx - 23].setpoint, recipe->hopstand[idx - 23].duration);
1105 else
1106 snprintf(pmpt, Config.lcd_cols + 1, "Hold for %3d mins", recipe->hopstand[idx - 23].duration);
1107 prompt(300, pmpt);
1108 break;
1109 }
1110
1111 key = keywait();
1112 if ((key == KEY_RETURN) || my_shutdown) {
1113 ncrc = crc32(ncrc, (const Bytef *)recipe, sizeof(a_recipe));
1114 if (ocrc != ncrc) {
1115 /*
1116 * Fix some user errors
1117 */
1118 for (i = 0; i < 8; i++)
1119 if (recipe->hops[i].boiltime > recipe->boiltime)
1120 recipe->hops[i].boiltime = recipe->boiltime;
1121 wrrecipes();
1122 }
1123 if (debug)
1124 fprintf(stdout, "End edit recipe `%s' %s\n", recipe->name, recipe->uuid);
1125 return;
1126 }
1127
1128 if ((key == KEY_UP) && (idx > 1))
1129 idx--;
1130 if ((key == KEY_DOWN) && (idx < 24))
1131 idx++;
1132
1133 if (key == KEY_ENTER) {
1134 switch(idx) {
1135 case 1: name = calloc(sizeof(char), 21);
1136 snprintf(name, 21, recipe->name);
1137 editName(name, (char *)"Recipe name");
1138 if (recipe->name)
1139 free(recipe->name);
1140 recipe->name = xstrcpy(name);
1141 free(name);
1142 break;
1143 case 2: name = calloc(sizeof(char), 21);
1144 snprintf(name, 21, recipe->code);
1145 editName(name, (char *)"Recipe code");
1146 if (recipe->code)
1147 free(recipe->code);
1148 recipe->code = xstrcpy(name);
1149 free(name);
1150 break;
1151 case 3: editInteger(&recipe->boiltime, 60, 240, 5, (char *)"Boil time:", (char *)"mins");
1152 break;
1153 case 4: editFloat(&recipe->coolto, 10.0, 30.0, (char *)" Cool to");
1154
1155 case 5:
1156 case 6:
1157 case 7:
1158 case 8:
1159 case 9:
1160 case 10:
1161 case 11:
1162 case 12: editMash(&recipe->mash[idx-5]);
1163 break;
1164 case 13:
1165 case 14:
1166 case 15:
1167 case 16:
1168 case 17:
1169 case 18:
1170 case 19:
1171 case 20:
1172 case 21:
1173 case 22: editHopaddition(&recipe->hops[idx-13], recipe->boiltime);
1174 break;
1175 case 23:
1176 case 24:
1177 case 25: editHopstand(&recipe->hopstand[idx-23]);
1178 break;
1179 }
1180 }
1181 }
1182 }
1183
1184
1185
1186 void addRecipe(int number)
1187 {
1188 a_recipe *tmpu, *recipe = (a_recipe *)malloc(sizeof(a_recipe));
1189 char name[81];
1190 uuid_t uu;
1191
1192 if (debug)
1193 fprintf(stdout, "Adding new recipe %d\n", number);
1194 recipe->next = NULL;
1195 recipe->uuid = malloc(37);
1196 uuid_generate(uu);
1197 uuid_unparse(uu, recipe->uuid);
1198 snprintf(name, 21, "New recipe %d", number);
1199 recipe->name = xstrcpy(name);
1200 snprintf(name, 21, "%04d", number);
1201 recipe->code = xstrcpy(name);
1202 recipe->boiltime = 90;
1203 recipe->coolto = 20.0;
1204 recipe->starttime = recipe->endtime = (time_t)0;
1205 /*
1206 * Initial mash schedule, set a single-step 67 degr. mash
1207 */
1208 recipe->mash[0].name = xstrcpy((char *)"Mash-in");
1209 recipe->mash[0].min = 20;
1210 recipe->mash[0].max = 80;
1211 recipe->mash[0].canskip = 0;
1212 recipe->mash[0].setpoint = 68.0;
1213 recipe->mash[0].skip = 0;
1214 recipe->mash[0].duration = 1;
1215 recipe->mash[1].name = xstrcpy((char *)"Phytase");
1216 recipe->mash[1].min = 25;
1217 recipe->mash[1].max = 55;
1218 recipe->mash[1].canskip = 1;
1219 recipe->mash[1].setpoint = 40.0;
1220 recipe->mash[1].skip = 1;
1221 recipe->mash[1].duration = 10;
1222 recipe->mash[2].name = xstrcpy((char *)"Glucanase");
1223 recipe->mash[2].min = 35;
1224 recipe->mash[2].max = 50;
1225 recipe->mash[2].canskip = 1;
1226 recipe->mash[2].setpoint = 45.0;
1227 recipe->mash[2].skip = 1;
1228 recipe->mash[2].duration = 10;
1229 recipe->mash[3].name = xstrcpy((char *)"Protease");
1230 recipe->mash[3].min = 45;
1231 recipe->mash[3].max = 60;
1232 recipe->mash[3].canskip = 1;
1233 recipe->mash[3].setpoint = 55.0;
1234 recipe->mash[3].skip = 1;
1235 recipe->mash[3].duration = 10;
1236 recipe->mash[4].name = xstrcpy((char *)"B-Amylase");
1237 recipe->mash[4].min = 50;
1238 recipe->mash[4].max = 70;
1239 recipe->mash[4].canskip = 1;
1240 recipe->mash[4].setpoint = 62.0;
1241 recipe->mash[4].skip = 1;
1242 recipe->mash[4].duration = 30;
1243 recipe->mash[5].name = xstrcpy((char *)"A-Amylase 1");
1244 recipe->mash[5].min = 60;
1245 recipe->mash[5].max = 76;
1246 recipe->mash[5].canskip = 1;
1247 recipe->mash[5].setpoint = 67.0;
1248 recipe->mash[5].skip = 1;
1249 recipe->mash[5].duration = 30;
1250 recipe->mash[6].name = xstrcpy((char *)"A-Amylase 2");
1251 recipe->mash[6].min = 60;
1252 recipe->mash[6].max = 76;
1253 recipe->mash[6].canskip = 0;
1254 recipe->mash[6].setpoint = 67.0;
1255 recipe->mash[6].skip = 0;
1256 recipe->mash[6].duration = 60;
1257 recipe->mash[7].name = xstrcpy((char *)"Mash-out");
1258 recipe->mash[7].min = 75;
1259 recipe->mash[7].max = 80;
1260 recipe->mash[7].canskip = 0;
1261 recipe->mash[7].setpoint = 78.0;
1262 recipe->mash[7].skip = 0;
1263 recipe->mash[7].duration = 10;
1264
1265 /*
1266 * Add 2 hop additions, maximum 10
1267 */
1268 recipe->hops[0].name = xstrcpy((char *)"Hops 1");
1269 recipe->hops[0].skip = 0;
1270 recipe->hops[0].boiltime = 90;
1271 recipe->hops[1].name = xstrcpy((char *)"Hops 2");
1272 recipe->hops[1].skip = 0;
1273 recipe->hops[1].boiltime = 5;
1274 recipe->hops[2].name = xstrcpy((char *)"Hops 3");
1275 recipe->hops[2].skip = 1;
1276 recipe->hops[2].boiltime = 0;
1277 recipe->hops[3].name = xstrcpy((char *)"Hops 4");
1278 recipe->hops[3].skip = 1;
1279 recipe->hops[3].boiltime = 0;
1280 recipe->hops[4].name = xstrcpy((char *)"Hops 5");
1281 recipe->hops[4].skip = 1;
1282 recipe->hops[4].boiltime = 0;
1283 recipe->hops[5].name = xstrcpy((char *)"Hops 6");
1284 recipe->hops[5].skip = 1;
1285 recipe->hops[5].boiltime = 0;
1286 recipe->hops[6].name = xstrcpy((char *)"Hops 7");
1287 recipe->hops[6].skip = 1;
1288 recipe->hops[6].boiltime = 0;
1289 recipe->hops[7].name = xstrcpy((char *)"Hops 8");
1290 recipe->hops[7].skip = 1;
1291 recipe->hops[7].boiltime = 0;
1292 recipe->hops[8].name = xstrcpy((char *)"Hops 9");
1293 recipe->hops[8].skip = 1;
1294 recipe->hops[8].boiltime = 0;
1295 recipe->hops[9].name = xstrcpy((char *)"Hops 10");
1296 recipe->hops[9].skip = 1;
1297 recipe->hops[9].boiltime = 0;
1298
1299 /*
1300 * Add 3 hopstands, disabled by default.
1301 */
1302 recipe->hopstand[0].name = xstrcpy((char *)"Hopstand hot");
1303 recipe->hopstand[0].min = 88;
1304 recipe->hopstand[0].max = 100;
1305 recipe->hopstand[0].hold = 0;
1306 recipe->hopstand[0].setpoint = 93.0;
1307 recipe->hopstand[0].skip = 1;
1308 recipe->hopstand[0].duration = 30;
1309 recipe->hopstand[1].name = xstrcpy((char *)"Hopstand default");
1310 recipe->hopstand[1].min = 72;
1311 recipe->hopstand[1].max = 77;
1312 recipe->hopstand[1].hold = 0;
1313 recipe->hopstand[1].setpoint = 75.0;
1314 recipe->hopstand[1].skip = 1;
1315 recipe->hopstand[1].duration = 60;
1316 recipe->hopstand[2].name = xstrcpy((char *)"Hopstand cool");
1317 recipe->hopstand[2].min = 60;
1318 recipe->hopstand[2].max = 66;
1319 recipe->hopstand[2].hold = 0;
1320 recipe->hopstand[2].setpoint = 63.0;
1321 recipe->hopstand[2].skip = 1;
1322 recipe->hopstand[2].duration = 60;
1323
1324 editRecipe(recipe);
1325
1326 if (recipes == NULL) {
1327 recipes = recipe;
1328 } else {
1329 for (tmpu = recipes; tmpu; tmpu = tmpu->next) {
1330 if (tmpu->next == NULL) {
1331 tmpu->next = recipe;
1332 break;
1333 }
1334 }
1335 }
1336 syslog(LOG_NOTICE, "Recipe %d added", number);
1337 if (debug)
1338 fprintf(stdout, "Recipe %d added\n", number);
1339 }
1340
1341
1342
1343 void editRecipes(void)
1344 {
1345 int total, i, key, choice = 1;;
1346 a_recipe *recipe;
1347 char pmpt[81];
1348
1349 prompt(0, NULL);
1350 for (;;) {
1351 total = 0;
1352 for (recipe = recipes; recipe; recipe = recipe->next) {
1353 total++;
1354 }
1355
1356 if (debug)
1357 fprintf(stdout, "editRecipes total=%d choice=%d\n", total, choice);
1358
1359 i = 0;
1360 if (total) {
1361 for (recipe = recipes; recipe; recipe = recipe->next) {
1362 i++;
1363 if (i == choice)
1364 break;
1365 }
1366 }
1367
1368 prompt(102, NULL); /* " SETUP MENU " */
1369 prompt(221, NULL); /* " Select Recipe " */
1370 if (total) {
1371 snprintf(pmpt, Config.lcd_cols + 1, "%s %s ", recipe->code, recipe->name);
1372 prompt(300, pmpt);
1373 }
1374 if (total == 0)
1375 prompt(416, NULL); /* "add --- quit --- " */
1376 else if (total == 1)
1377 prompt(415, NULL); /* "add --- quit ok " */
1378 else if (total && (choice == 1))
1379 prompt(414, NULL); /* "add dwn quit ok " */
1380 else if (total && (choice == total))
1381 prompt(404, NULL); /* " up --- quit ok " */
1382 else
1383 prompt(403, NULL); /* " up dwn quit ok " */
1384
1385 key = keywait();
1386 if ((key == KEY_RETURN) || my_shutdown)
1387 return;
1388 if (total && (key == KEY_ENTER)) {
1389 editRecipe(recipe);
1390 prompt(0, NULL);
1391 }
1392 if (key == KEY_UP) {
1393 if ((total == 1) || (choice == 1))
1394 addRecipe(total + 1);
1395 else if (choice > 1)
1396 choice--;
1397 }
1398 if ((key == KEY_DOWN) && (total > 1) && (choice < total))
1399 choice++;
1400 }
1401 }
1402
1403
1404
1405 void editUnits(void)
1406 {
1407 int total, i, key, choice = 1;;
1408 units_list *unit;
1409 char pmpt[81];
1410
1411 prompt(0, NULL);
1412 for (;;) {
1413 total = 0;
1414 for (unit = Config.units; unit; unit = unit->next) {
1415 total++;
1416 }
1417
1418 if (debug)
1419 fprintf(stdout, "editUnits total=%d choice=%d\n", total, choice);
1420
1421 if (total == 0) {
1422 /*
1423 * Impossible unless first setup was skipped
1424 */
1425 addUnit(1);
1426 total = 1;
1427 } else {
1428 i = 0;
1429 for (unit = Config.units; unit; unit = unit->next) {
1430 i++;
1431 if (i == choice)
1432 break;
1433 }
1434 prompt(102, NULL); /* " SETUP MENU " */
1435 prompt(222, NULL); /* " Select Brewsystem " */
1436 snprintf(pmpt, Config.lcd_cols + 1, "%s ", unit->name);
1437 prompt(300, pmpt);
1438 if (total == 1)
1439 prompt(415, NULL); /* "add --- quit ok " */
1440 else if (choice == 1)
1441 prompt(414, NULL); /* "add dwn quit ok " */
1442 else if (choice == total)
1443 prompt(404, NULL); /* " up --- quit ok " */
1444 else
1445 prompt(403, NULL); /* " up dwn quit ok " */
1446
1447 key = keywait();
1448 if ((key == KEY_RETURN) || my_shutdown)
1449 return;
1450 if (key == KEY_ENTER) {
1451 editUnit(unit);
1452 prompt(0, NULL);
1453 }
1454 if (key == KEY_UP) {
1455 if ((total == 1) || (choice == 1))
1456 addUnit(total + 1);
1457 else if (choice > 1)
1458 choice--;
1459 }
1460 if ((key == KEY_DOWN) && (total > 1) && (choice < total))
1461 choice++;
1462 }
1463 }
1464 }
1465
1466
1467
1468 void setup(void)
1469 {
1470 int key, option = 202;
1471
1472 for (;;) {
1473 if (debug)
1474 fprintf(stdout, "setup() option=%d\n", option);
1475 prompt(0, NULL);
1476 prompt(102, NULL); /* " SETUP MENU " */
1477 prompt(option, NULL);
1478 if (option == 202)
1479 prompt(402, NULL); /* "--- dwn quit ok " */
1480 #ifdef USE_SIMULATOR
1481 else if (option == 205)
1482 #else
1483 else if (option == 204)
1484 #endif
1485 prompt(404, NULL); /* " up --- quit ok " */
1486 else
1487 prompt(403, NULL); /* " up dwn quit ok " */
1488
1489 key = keywait();
1490
1491 if ((key == KEY_RETURN) || my_shutdown)
1492 return;
1493 if ((key == KEY_UP) && (option > 202)) {
1494 option--;
1495 }
1496 #ifdef USE_SIMULATOR
1497 if ((key == KEY_DOWN) && (option < 205)) {
1498 #else
1499 if ((key == KEY_DOWN) && (option < 204)) {
1500 #endif
1501 option++;
1502 }
1503
1504 if (key == KEY_ENTER) {
1505 switch(option) {
1506 case 202: editRecipes();
1507 break;
1508 case 203: editUnits();
1509 break;
1510 case 204: // devices
1511 break;
1512 #ifdef USE_SIMULATOR
1513 case 205: // simulator
1514 break;
1515 #endif
1516 }
1517 if (my_shutdown)
1518 return;
1519 }
1520 }
1521 }
1522
1523

mercurial