# HG changeset patch # User Michiel Broek # Date 1450388754 -3600 # Node ID a1da58215b6529a07232fb5dca21458b957d019d # Parent 830ae3c3ef98e5d97b5af3de2ed1769da62360d0 Completed the recipe editor. diff -r 830ae3c3ef98 -r a1da58215b65 brewco/brewco.h --- a/brewco/brewco.h Wed Dec 16 22:54:53 2015 +0100 +++ b/brewco/brewco.h Thu Dec 17 22:45:54 2015 +0100 @@ -225,6 +225,7 @@ typedef struct _hop_addition { char *name; /* Hop name */ + int skip; /* Skip addition */ int boiltime; /* -1=fwh, 0..boiltime */ } hop_addition; diff -r 830ae3c3ef98 -r a1da58215b65 brewco/prompt.c --- a/brewco/prompt.c Wed Dec 16 22:54:53 2015 +0100 +++ b/brewco/prompt.c Thu Dec 17 22:45:54 2015 +0100 @@ -108,6 +108,12 @@ break; case 193: snprintf(message, Config.lcd_cols + 1, " Edit brewsystem "); break; + case 194: snprintf(message, Config.lcd_cols + 1, " Edit Mashstep "); + break; + case 195: snprintf(message, Config.lcd_cols + 1, " Edit Addition "); + break; + case 196: snprintf(message, Config.lcd_cols + 1, " Edit Hopstand "); + break; case 200: snprintf(message, Config.lcd_cols + 1, text); break; case 202: snprintf(message, Config.lcd_cols + 1, " Manage Recipes "); diff -r 830ae3c3ef98 -r a1da58215b65 brewco/rdrecipes.c --- a/brewco/rdrecipes.c Wed Dec 16 22:54:53 2015 +0100 +++ b/brewco/rdrecipes.c Thu Dec 17 22:45:54 2015 +0100 @@ -184,23 +184,25 @@ return 1; } for (i = 0; i < 10; i++) { - if (recipe->hops[i].name) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "HOPADDITION")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", recipe->hops[i].name)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BOILTIME", "%d", recipe->hops[i].boiltime)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } + if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "HOPADDITION")) < 0) { + syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); + return 1; + } + if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", recipe->hops[i].name)) < 0) { + syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); + return 1; + } + if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP", "%s", recipe->hops[i].skip ? "YES":"NO")) < 0) { + syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); + return 1; + } + if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BOILTIME", "%d", recipe->hops[i].boiltime)) < 0) { + syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); + return 1; + } + if ((rc = xmlTextWriterEndElement(writer)) < 0) { + syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); + return 1; } } if ((rc = xmlTextWriterEndElement(writer)) < 0) { @@ -438,6 +440,16 @@ if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"NAME"))) { recipe->hops[i].name = (char *)xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); } + if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"SKIP"))) { + key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); + for (j = 0; j < 2; j++) { + if (! xmlStrcmp(key, (const xmlChar *)SKIPYN[j])) { + recipe->hops[i].skip = j; + break; + } + } + xmlFree(key); + } if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"BOILTIME"))) { key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); if (sscanf((const char *)key, "%d", &ival) == 1) diff -r 830ae3c3ef98 -r a1da58215b65 brewco/setup.c --- a/brewco/setup.c Wed Dec 16 22:54:53 2015 +0100 +++ b/brewco/setup.c Thu Dec 17 22:45:54 2015 +0100 @@ -349,6 +349,193 @@ +void editMash(mash_step *mash) +{ + int key, idx = 1, lo, hi; + char pmpt[81]; + + for (;;) { + prompt(0, NULL); + prompt(194, NULL); + + if (mash->canskip) { + lo = 1; + if (mash->skip) + hi = 1; + else + hi = 3; + } else { + lo = 2; + hi = 3; + } + if (idx < lo) + idx = lo; + if (idx > hi) + idx = hi; + if (debug) + fprintf(stdout, "editMash canskip=%d skip=%d lo=%d hi=%d idx=%d\n", mash->canskip, mash->skip, lo, hi, idx); + + switch (idx) { + case 1: snprintf(pmpt, Config.lcd_cols + 1, " Mashstep skip: %s", mash->skip ? (char *)"Yes":(char *)"No"); + break; + case 2: snprintf(pmpt, Config.lcd_cols + 1, " Setpoint: %5.1f\001", mash->setpoint); + break; + case 3: snprintf(pmpt, Config.lcd_cols + 1, " Duration: %3d mins", mash->duration); + break; + } + prompt(200, pmpt); + + if (lo == hi) + prompt(405, NULL); /* "--- --- quit ok " */ + else if (idx == lo) + prompt(402, NULL); /* "--- dwn quit ok " */ + else if (idx == hi) + prompt(404, NULL); /* " up --- quit ok " */ + else + prompt(403, NULL); /* " up dwn quit ok " */ + + key = keywait(); + if ((key == KEY_RETURN) || my_shutdown) + return; + if ((key == KEY_UP) && (idx > lo)) + idx--; + if ((key == KEY_DOWN) && (idx < hi)) + idx++; + if (key == KEY_ENTER) { + switch(idx) { + case 1: toggleYesNo(&mash->skip, (char *)" Mashstep skip"); + break; + case 2: editFloat(&mash->setpoint, mash->min, mash->max, (char *)" Setpoint"); + break; + case 3: editInteger(&mash->duration, 1, 120, 1, (char *)" Duration", (char *)"mins"); + break; + } + } + } +} + + + +void editHopaddition(hop_addition *hops, int boiltime) +{ + int key, idx = 1, hi; + char pmpt[81]; + + for (;;) { + prompt(0, NULL); + prompt(195, NULL); + + if (hops->skip) + hi = 1; + else + hi = 2; + if (idx > hi) + idx = hi; + if (debug) + fprintf(stdout, "editHopaddition skip=%d hi=%d idx=%d\n", hops->skip, hi, idx); + + switch (idx) { + case 1: snprintf(pmpt, Config.lcd_cols + 1, "Addition skip: %s", hops->skip ? (char *)"Yes":(char *)"No"); + break; + case 2: snprintf(pmpt, Config.lcd_cols + 1, " Boil for: %3d mins", hops->boiltime); + break; + } + prompt(200, pmpt); + + if (hi == 1) + prompt(405, NULL); /* "--- --- quit ok " */ + else if (idx == 1) + prompt(402, NULL); /* "--- dwn quit ok " */ + else if (idx == hi) + prompt(404, NULL); /* " up --- quit ok " */ + else + prompt(403, NULL); /* " up dwn quit ok " */ + + key = keywait(); + if ((key == KEY_RETURN) || my_shutdown) + return; + if ((key == KEY_UP) && (idx > 1)) + idx--; + if ((key == KEY_DOWN) && (idx < hi)) + idx++; + if (key == KEY_ENTER) { + switch (idx) { + case 1: toggleYesNo(&hops->skip, (char *)"Addition skip"); + break; + case 2: editInteger(&hops->boiltime, -1, boiltime, 1, (char *)" Boil for", (char *)"mins"); + break; + } + } + } +} + + + +void editHopstand(hop_stand *hops) +{ + int key, idx = 1, hi; + char pmpt[81]; + + for (;;) { + prompt(0, NULL); + prompt(196, NULL); + + if (hops->skip) + hi = 1; + else + hi = 4; + if (idx < 1) + idx = 1; + if (idx > hi) + idx = hi; + if (debug) + fprintf(stdout, "editHopstand skip=%d hi=%d idx=%d\n", hops->skip, hi, idx); + + switch (idx) { + case 1: snprintf(pmpt, Config.lcd_cols + 1, "Hopstand skip: %s", hops->skip ? (char *)"Yes":(char *)"No"); + break; + case 2: snprintf(pmpt, Config.lcd_cols + 1, "Hold temperature: %s", hops->hold ? (char *)"Yes":(char *)"No"); + break; + case 3: snprintf(pmpt, Config.lcd_cols + 1, " Setpoint: %5.1f\001", hops->setpoint); + break; + case 4: snprintf(pmpt, Config.lcd_cols + 1, " Duration: %3d mins", hops->duration); + break; + } + prompt(200, pmpt); + + if (hi == 1) + prompt(405, NULL); /* "--- --- quit ok " */ + else if (idx == 1) + prompt(402, NULL); /* "--- dwn quit ok " */ + else if (idx == hi) + prompt(404, NULL); /* " up --- quit ok " */ + else + prompt(403, NULL); /* " up dwn quit ok " */ + + key = keywait(); + if ((key == KEY_RETURN) || my_shutdown) + return; + if ((key == KEY_UP) && (idx > 1)) + idx--; + if ((key == KEY_DOWN) && (idx < hi)) + idx++; + if (key == KEY_ENTER) { + switch(idx) { + case 1: toggleYesNo(&hops->skip, (char *)"Hopstand skip"); + break; + case 2: toggleYesNo(&hops->hold, (char *)"Hold temperature"); + break; + case 3: editFloat(&hops->setpoint, hops->min, hops->max, (char *)" Setpoint"); + break; + case 4: editInteger(&hops->duration, 10, 240, 10, (char *)" Duration", (char *)"mins"); + break; + } + } + } +} + + + void editSensor(char *uuid, char *text) { char pmpt[81]; @@ -831,7 +1018,7 @@ */ void editRecipe(a_recipe *recipe) { - int idx = 1, key; + int idx = 1, i, key; char pmpt[81], *name; uLong ocrc, ncrc; @@ -878,9 +1065,9 @@ case 11: snprintf(pmpt, Config.lcd_cols + 1, "Mash: %s", recipe->mash[idx - 4].name); prompt(200, pmpt); if (recipe->mash[idx - 4].skip) - snprintf(pmpt, Config.lcd_cols + 1, "Skipped"); + snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); else - snprintf(pmpt, Config.lcd_cols + 1, "Sv %4.1f\001 %3d mins", recipe->mash[idx - 4].setpoint, recipe->mash[idx - 4].duration); + snprintf(pmpt, Config.lcd_cols + 1, " Sv %4.1f\001 %3d mins", recipe->mash[idx - 4].setpoint, recipe->mash[idx - 4].duration); prompt(300, pmpt); break; case 12: @@ -892,22 +1079,24 @@ case 18: case 19: case 20: - case 21: snprintf(pmpt, Config.lcd_cols + 1, "Hop: %s", recipe->hops[idx - 12].name); + case 21: snprintf(pmpt, Config.lcd_cols + 1, "Add: %s", recipe->hops[idx - 12].name); prompt(200, pmpt); - if (recipe->hops[idx - 12].name) { + if (recipe->hops[idx - 12].skip) + snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); + else { if (recipe->hops[idx - 12].boiltime == -1) - snprintf(pmpt, Config.lcd_cols + 1, "First Wort Hop"); + snprintf(pmpt, Config.lcd_cols + 1, " First Wort Hop"); else - snprintf(pmpt, Config.lcd_cols + 1, "Add at %3d mins", recipe->hops[idx - 12].boiltime); - prompt(300, pmpt); + snprintf(pmpt, Config.lcd_cols + 1, " Boil for %3d mins", recipe->hops[idx - 12].boiltime); } + prompt(300, pmpt); break; case 22: case 23: case 24: snprintf(pmpt, Config.lcd_cols + 1, "Hopstand: %s", recipe->hopstand[idx - 22].name); prompt(200, pmpt); if (recipe->hopstand[idx - 22].skip) - snprintf(pmpt, Config.lcd_cols + 1, "Skipped"); + snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); else if (recipe->hopstand[idx - 22].hold) snprintf(pmpt, Config.lcd_cols + 1, "Hold at %4.1f %3d mins", recipe->hopstand[idx - 22].setpoint, recipe->hopstand[idx - 22].duration); else @@ -919,8 +1108,15 @@ key = keywait(); if ((key == KEY_RETURN) || my_shutdown) { ncrc = crc32(ncrc, (const Bytef *)recipe, sizeof(a_recipe)); - if (ocrc != ncrc) + if (ocrc != ncrc) { + /* + * Fix some user errors + */ + for (i = 0; i < 8; i++) + if (recipe->hops[i].boiltime > recipe->boiltime) + recipe->hops[i].boiltime = recipe->boiltime; wrrecipes(); + } if (debug) fprintf(stdout, "End edit recipe `%s' %s\n", recipe->name, recipe->uuid); return; @@ -951,6 +1147,30 @@ break; case 3: editInteger(&recipe->boiltime, 60, 240, 5, (char *)"Boil time:", (char *)"mins"); break; + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: editMash(&recipe->mash[idx-4]); + break; + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: editHopaddition(&recipe->hops[idx-12], recipe->boiltime); + break; + case 22: + case 23: + case 24: editHopstand(&recipe->hopstand[idx-22]); + break; } } } @@ -963,7 +1183,6 @@ a_recipe *tmpu, *recipe = (a_recipe *)malloc(sizeof(a_recipe)); char name[81]; uuid_t uu; - int i; if (debug) fprintf(stdout, "Adding new recipe %d\n", number); @@ -1041,14 +1260,35 @@ * Add 2 hop additions, maximum 10 */ recipe->hops[0].name = xstrcpy((char *)"Hops 1"); + recipe->hops[0].skip = 0; recipe->hops[0].boiltime = 90; recipe->hops[1].name = xstrcpy((char *)"Hops 2"); + recipe->hops[1].skip = 0; recipe->hops[1].boiltime = 5; - for (i = 2; i < 10; i++) { - recipe->hops[i].name = NULL; - recipe->hops[i].boiltime = 0; - } - + recipe->hops[2].name = xstrcpy((char *)"Hops 3"); + recipe->hops[2].skip = 1; + recipe->hops[2].boiltime = 0; + recipe->hops[3].name = xstrcpy((char *)"Hops 4"); + recipe->hops[3].skip = 1; + recipe->hops[3].boiltime = 0; + recipe->hops[4].name = xstrcpy((char *)"Hops 5"); + recipe->hops[4].skip = 1; + recipe->hops[4].boiltime = 0; + recipe->hops[5].name = xstrcpy((char *)"Hops 6"); + recipe->hops[5].skip = 1; + recipe->hops[5].boiltime = 0; + recipe->hops[6].name = xstrcpy((char *)"Hops 7"); + recipe->hops[6].skip = 1; + recipe->hops[6].boiltime = 0; + recipe->hops[7].name = xstrcpy((char *)"Hops 8"); + recipe->hops[7].skip = 1; + recipe->hops[7].boiltime = 0; + recipe->hops[8].name = xstrcpy((char *)"Hops 9"); + recipe->hops[8].skip = 1; + recipe->hops[8].boiltime = 0; + recipe->hops[9].name = xstrcpy((char *)"Hops 10"); + recipe->hops[9].skip = 1; + recipe->hops[9].boiltime = 0; /* * Add 3 hopstands, disabled by default.