diff -r 5a237a99a793 -r d5bc44183aa4 brewco/brewco.c --- a/brewco/brewco.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1633 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2015 - * - * Michiel Broek - * - * This file is part of the mbsePi-apps - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * mbsePi-apps is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ThermFerm; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "brewco.h" -#include "rdconfig.h" -#include "rdsession.h" -#include "rdrecipes.h" -#include "util.h" -#include "xutil.h" -#include "lcd-pcf8574.h" -#include "slcd.h" -#include "lock.h" -#include "devices.h" -#include "keyboard.h" -#include "simulator.h" -#include "prompt.h" -#include "setup.h" -#include "logger.h" - - - -int my_shutdown = FALSE; -int mlt_pump_state = 0; - -double hltInput; /* HLT PID variables */ -double hltOutput; -double hltSetpoint; -double mltInput; /* MLT PID variables */ -double mltOutput; -double mltSetpoint; - -extern int debug; -extern sys_config Config; -extern a_recipe *recipes; -extern int lcdHandle; -extern int slcdHandle; -extern int sock; - -#ifdef USE_SIMULATOR -extern int SIM_cooler; -#endif -char *etcpath = NULL; -char *varpath = NULL; - - - -#ifndef HAVE_WIRINGPI_H -pthread_t threads[5]; -#endif - - -#define MANUAL_NONE 0 -#define MANUAL_SELHLT 1 -#define MANUAL_SELMLT 2 -#define MANUAL_HLT 11 -#define MANUAL_MLT 12 - -#define PERC_INIT 0 -#define PERC_MLT 1 -#define PERC_HLT 2 -#define PERC_REST 3 - - -int manual = MANUAL_NONE; - - - -/* - * CGRAM characters - */ -unsigned char degC[8] = { 0b01000, 0b10100, 0b01000, 0b00111, 0b01000, 0b01000, 0b01000, 0b00111 }; -unsigned char degF[8] = { 0b01000, 0b10100, 0b01000, 0b00111, 0b00100, 0b00110, 0b00100, 0b00100 }; -unsigned char SP_Symbol[8] = { 0b11100, 0b10000, 0b11100, 0b00111, 0b11101, 0b00111, 0b00100, 0b00100 }; -unsigned char PumpONOFF[8] = { 0b00000, 0b01110, 0b01010, 0b01110, 0b01000, 0b01000, 0b01000, 0b00000 }; -unsigned char RevPumpONOFF[8] = { 0b11111, 0b10001, 0b10101, 0b10001, 0b10111, 0b10111, 0b10111, 0b11111 }; -unsigned char HeatONOFF[8] = { 0b00000, 0b01010, 0b01010, 0b01110, 0b01110, 0b01010, 0b01010, 0b00000 }; -unsigned char RevHeatONOFF[8] = { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 }; -unsigned char Language[8] = { 0b11111, 0b00010, 0b01000, 0b11111, 0b00000, 0b10001, 0b10101, 0b11111 }; - - -void help(void); -void die(int); - - - -void help(void) -{ - fprintf(stdout, "mbsePi-apps brewco v%s starting\n\n", VERSION); - fprintf(stdout, "Usage: brewco [-d] [-h]\n"); - fprintf(stdout, " -d --debug Debug and run in foreground\n"); - fprintf(stdout, " -h --help Display this help\n"); -} - - - -void die(int onsig) -{ - switch (onsig) { -#ifdef USE_SIMULATOR - case SIGUSR1: syslog(LOG_NOTICE, "Got SIGUSR1, start cooler"); - SIM_cooler = TRUE; - return; - case SIGUSR2: syslog(LOG_NOTICE, "Got SIGUSR2, stop cooler"); - SIM_cooler = FALSE; - return; -#endif - case SIGHUP: syslog(LOG_NOTICE, "Got SIGHUP, shutting down"); - break; - case SIGINT: syslog(LOG_NOTICE, "Keyboard interrupt, shutting down"); - break; - case SIGTERM: syslog(LOG_NOTICE, "Got SIGTERM, shutting down"); - break; - case SIGSEGV: syslog(LOG_NOTICE, "Got SIGSEGV, shutting down"); - my_shutdown = TRUE; - exit(SIGSEGV); - break; - default: syslog(LOG_NOTICE, "die() on signal %d", onsig); - } - - my_shutdown = TRUE; -} - - - -void tempstatus(void) -{ - char text[81]; - - snprintf(text, 8, "%6.2f\001", hltInput); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 1, 1); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 1, 1); - slcdPuts(slcdHandle, text); - - snprintf(text, 8, "%6.2f\001", mltInput); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 10, 1); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 10, 1); - slcdPuts(slcdHandle, text); -} - - - -/* - * Third line, show setPoints or heater percentage. - */ -void percstatus(int which) -{ - char text[21]; - - if (which) - snprintf(text, 8, "%6.2f\002", hltSetpoint); - else - snprintf(text, 8, "HLT%3d%%", (int)hltOutput); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 1, 2); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 1, 2); - slcdPuts(slcdHandle, text); - - if (which) - snprintf(text, 8, "%6.2f\002", mltSetpoint); - else - snprintf(text, 8, "MLT%3d%%", (int)mltOutput); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 10, 2); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 10, 2); - slcdPuts(slcdHandle, text); -} - - - -/* - * Third line during boil, only MLT status - */ -void mltstatus(void) -{ - char text[21]; - - snprintf(text, 20, "MLT %3d%% %6.2f\002 ", (int)mltOutput, mltSetpoint); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 0, 2); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 0, 2); - slcdPuts(slcdHandle, text); -} - - - -void timestatus(int row, int timeval) -{ - char text[21]; - int hours, mins, val = timeval; - - hours = val / 3600; - val -= (hours * 3600); - mins = val / 60; - val -= (mins * 60); - - snprintf(text, 20, " %02d:%02d:%02d ", hours, mins, val); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 0, row); - lcdPuts(lcdHandle, text); -#endif - slcdPosition(slcdHandle, 0, row); - slcdPuts(slcdHandle, text); -} - - - -int set_HLT_heater(units_list *unit, int state, double val) -{ - if (strcmp(unit->hlt_heater.uuid, (char *)"00000000-0000-0000-0000-000000000000") == 0) - return 0; - - hltSetpoint = val; - - if (state && (PID_getMode(unit->PID_hlt) == P_MANUAL)) { - hlt_status(1); - PID_setMode(unit->PID_hlt, P_AUTOMATIC); - return 1; - } - if (! state && (PID_getMode(unit->PID_hlt) == P_AUTOMATIC)) { - hlt_status(0); - PID_setMode(unit->PID_hlt, P_MANUAL); - return 1; - } - - return 0; -} - - - -int set_MLT_heater(units_list *unit, int state, double val) -{ - if (strcmp(unit->mlt_heater.uuid, (char *)"00000000-0000-0000-0000-000000000000") == 0) - return 0; - - mltSetpoint = val; - - if (state && (PID_getMode(unit->PID_mlt) == P_MANUAL)) { - mlt_status(1); - PID_setMode(unit->PID_mlt, P_AUTOMATIC); - return 1; - } - if (! state && (PID_getMode(unit->PID_mlt) == P_AUTOMATIC)) { - mlt_status(0); - PID_setMode(unit->PID_mlt, P_MANUAL); - return 1; - } - - return 0; -} - - - -int set_MLT_pump(units_list *unit, int state) -{ - if (strcmp(unit->mlt_pump.uuid, (char *)"00000000-0000-0000-0000-000000000000") == 0) - return 0; - - if (state && ! mlt_pump_state) { - device_out(unit->mlt_pump.uuid, 1); - mlt_pump_state = 1; - return 1; - } - if (! state && mlt_pump_state) { - device_out(unit->mlt_pump.uuid, 0); - mlt_pump_state = 0; - return 1; - } - - return 0; -} - - - -void automatic_brew(units_list *, brew_session *, a_recipe *, int, int); -void automatic_brew(units_list *unit, brew_session *brew, a_recipe *recipe, int dosave, int seconds) -{ - int key, save = dosave, i; - char data[128]; - static int mash_fase = MASH_NA, hopstand = 0, last_step = STEP_NA, last_fase = -1, oldsec = 75, startdelay = 0; - - if (brew->brewstep != last_step) { - snprintf(data, 40, brewstep_name(last_step)); - syslog(LOG_NOTICE, "AUTO: brewstep %s to %s", data, brewstep_name(brew->brewstep)); - } - - switch (brew->brewstep) { - case STEP_NA: if (debug) - fprintf(stdout, "auto: init recipe: %s-%s unit: %s\n", recipe->code, recipe->name, unit->name); - syslog(LOG_NOTICE, "AUTO: starting new brew, recipe: %s-%s unit: %s", recipe->code, recipe->name, unit->name); - brew->brewstep = STEP_BREWINIT; - break; - - case STEP_BREWINIT: prompt(103, NULL); /* " AUTOMATIC MODE " */ - prompt(207, NULL); /* " Delay start? " */ - prompt(300, NULL); /* " " */ - prompt(407, NULL); /* "--- --- No Yes " */ - if (debug) - fprintf(stdout, "step brewinit\n"); - key = keywait(); - if (key == KEY_RETURN) { - brew->brewstep = STEP_WATERCHECK; - startdelay = 0; - syslog(LOG_NOTICE, "AUTO: brew initialize, direct start selected"); - break; - } - if (key == KEY_ENTER) { - startdelay = 30; - editInteger(&startdelay, 10, 960, 10, (char *)"Start delay", (char *)"mins"); - } - syslog(LOG_NOTICE, "AUTO: brew initialize"); - brew->brewstep = STEP_WATERCHECK; - break; - - case STEP_WATERCHECK: if (brew->brewstep != last_step) { - prompt(111, NULL); /* "AUTO --> Mash In " */ - prompt(209, NULL); /* " Water Added? " */ - prompt(300, NULL); - prompt(407, NULL); /* "--- --- No Yes " */ - last_step = brew->brewstep; - } - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_ENTER) { - brew->brewstep = STEP_PUMPPRIME; - syslog(LOG_NOTICE, "AUTO: confirmed water added"); - } - if (key == KEY_RETURN) { - syslog(LOG_NOTICE, "AUTO: aborted water added"); - brew->brewstep = STEP_CLEANUP; - } - break; - - case STEP_PUMPPRIME: if (brew->brewstep != last_step) { - prompt(100, NULL); /* " " */ - prompt(210, NULL); /* " Pump Prime " */ - prompt(300, NULL); /* " " */ - prompt(400, NULL); /* " " */ - hlt_status(0); - mlt_status(0); - last_step = brew->brewstep; - } - for (i = 1; i < 6; i++) { - if (set_MLT_pump(unit, 1)) - syslog(LOG_NOTICE, "AUTO: pump prime %d turn %s MLT pump", i, mlt_pump_state ? "on":"off"); - usleep(750000 + (i * 250000)); /* 250 + i * 250 mSec */ - if (set_MLT_pump(unit, 0)) - syslog(LOG_NOTICE, "AUTO: pump prime %d turn %s MLT pump", i, mlt_pump_state ? "on":"off"); - usleep(350000); /* 350 mSec */ - } - brew->brewstep = STEP_WAITSTART; - break; - - case STEP_WAITSTART: if (startdelay == 0) { - brew->brewstep = STEP_PREMASH; - break; - } - if (brew->brewstep != last_step) { - brew->timeout = startdelay * 60; - prompt(111, NULL); /* "AUTO --> Mash In " */ - prompt(212, NULL); /* " To be started in " */ - prompt(410, NULL); /* " Continue: Yes No " */ - last_step = brew->brewstep; - } - if (oldsec != seconds) { - timestatus(2, brew->timeout); - brew->timeout--; - if (brew->timeout <= 0) { - syslog(LOG_NOTICE, "AUTO: delayed start time reached"); - brew->brewstep = STEP_PREMASH; - } - oldsec = seconds; - } - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_RETURN) { - syslog(LOG_NOTICE, "AUTO: delayed start skipped by user"); - brew->brewstep = STEP_PREMASH; - } - break; - - case STEP_PREMASH: if (brew->brewstep != last_step) { - prompt(111, NULL); /* "AUTO --> Prepare " */ - prompt(300, NULL); /* " " */ - prompt(418, NULL); /* "--- --- Pause --- " */ - tempstatus(); - hlt_status(1); - mlt_status(1); - pump_status(unit->pump_premash); - last_step = brew->brewstep; - initlog(brew->name); - } - if (oldsec != seconds) { - tempstatus(); - percstatus((seconds / 2) % 4); - oldsec = seconds; - } - if (set_HLT_heater(unit, 1, 85.0)) - syslog(LOG_NOTICE, "AUTO: premash turn on HLT at %6.2f", hltSetpoint); - if (set_MLT_heater(unit, 1, 10.0)) - syslog(LOG_NOTICE, "AUTO: premash turn on MLT at %6.2f", mltSetpoint); - if (set_MLT_pump(unit, unit->pump_premash)) - syslog(LOG_NOTICE, "AUTO: premash turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (hltInput >= 85.0) { - brew->brewstep = STEP_MASHING; - brew->mashstep = 0; - mash_fase = MASH_NA; - save = TRUE; - } - break; - - case STEP_MASHING: if (brew->brewstep != last_step) { - prompt(111 + brew->mashstep, NULL); /* "AUTO --> [mashname] " */ - prompt(300, NULL); /* " " */ - prompt(418, NULL); /* "--- --- Pause --- " */ - tempstatus(); - hlt_status(1); - mlt_status(1); - pump_status(unit->pump_onmash); - last_step = brew->brewstep; - } - if (set_HLT_heater(unit, 1, 85.0)) - syslog(LOG_NOTICE, "AUTO: mash turn on HLT at %6.2f", hltSetpoint); - if (set_MLT_heater(unit, 1, recipe->mash[brew->mashstep].setpoint)) - syslog(LOG_NOTICE, "AUTO: mash turn on MLT at %6.2f", mltSetpoint); - - switch (mash_fase) { - case MASH_NA: if (recipe->mash[brew->mashstep].skip) { - syslog(LOG_NOTICE, "AUTO: skipping mash step %d", brew->mashstep); - brew->mashstep++; - } else { - mltSetpoint = recipe->mash[brew->mashstep].setpoint; - brew->timeout = recipe->mash[brew->mashstep].duration * 60; - mash_fase = MASH_HEATING; - syslog(LOG_NOTICE, "AUTO: mash step %d fase NA, setpoint %6.2f, duration %d", - brew->mashstep, mltSetpoint, brew->timeout); - } - if (brew->mashstep == 0) { - brew->starttime = time(NULL); - save = TRUE; - } - break; - - case MASH_PROMPT: if (last_fase != mash_fase) { - prompt(111 + brew->mashstep, NULL); /* "AUTO --> [mashname] " */ - prompt(219, NULL); /* " Mash added? " */ - prompt(300, NULL); - prompt(407, NULL); /* "--- --- No Yes " */ - last_fase = mash_fase; - } - if (set_MLT_pump(unit, 0)) /* Off during mash add */ - syslog(LOG_NOTICE, "AUTO: mash turn %s MLT pump", mlt_pump_state ? "on":"off"); - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_ENTER) { - mash_fase = MASH_NA; - brew->mashstep++; - syslog(LOG_NOTICE, "AUTO: confirmed mash added"); - } - if (key == KEY_RETURN) { - syslog(LOG_NOTICE, "AUTO: aborted mash added"); - brew->brewstep = STEP_CLEANUP; - brew->mashstep = 0; - } - break; - - case MASH_IODINE: if (last_fase != mash_fase) { - prompt(118, NULL); /* "AUTO --> Mash Out " */ - prompt(213, NULL); /* " Iodine test " */ - timestatus(2, brew->timeout); - prompt(410, NULL); /* " Continue: Yes No " */ - last_fase = mash_fase; - } - if (set_MLT_pump(unit, unit->pump_onmash)) - syslog(LOG_NOTICE, "AUTO: mash turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (oldsec != seconds) { - brew->timeout--; - timestatus(2, brew->timeout); - if (brew->timeout <= 0) { - syslog(LOG_NOTICE, "AUTO: mash IODINE test timeout"); - mash_fase = MASH_NA; - brew->mashstep++; - } - oldsec = seconds; - } - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_RETURN) { - syslog(LOG_NOTICE, "AUTO: mash IODINE test confirmed"); - mash_fase = MASH_NA; - brew->mashstep++; - } - if (key == KEY_ENTER) { - syslog(LOG_NOTICE, "AUTO: mash IODINE test declined"); - mash_fase = MASH_REST; - brew->timeout = 600; /* Add 10 more minutes */ - } - break; - - case MASH_HEATING: if (last_fase != mash_fase) { - prompt(111 + brew->mashstep, NULL); /* "AUTO --> [mashname] " */ - prompt(200, NULL); - prompt(300, NULL); - prompt(418, NULL); /* "--- --- Pause --- " */ - hlt_status(1); - mlt_status(1); - pump_status(unit->pump_onmash); - last_fase = mash_fase; - syslog(LOG_NOTICE, "AUTO: mash step %d fase HEATING started", brew->mashstep); - } - if (set_MLT_pump(unit, unit->pump_onmash)) - syslog(LOG_NOTICE, "AUTO: mash turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (oldsec != seconds) { - tempstatus(); - percstatus((seconds / 2) % 4); - oldsec = seconds; - } - if (mltInput > mltSetpoint) { - syslog(LOG_NOTICE, "AUTO: mash step %d fase HEATING reached %6.2f", brew->mashstep, mltSetpoint); - mash_fase = MASH_REST; - } - break; - - case MASH_REST: if (last_fase != mash_fase) { - prompt(111 + brew->mashstep, NULL); /* "AUTO --> [mashname] " */ - prompt(200, NULL); - prompt(300, NULL); - prompt(418, NULL); /* "--- --- Pause --- " */ - hlt_status(1); - mlt_status(1); - pump_status(unit->pump_onmash); - last_fase = mash_fase; - } - if (oldsec != seconds) { - tempstatus(); - timestatus(2, brew->timeout); - if (brew->mashstep == 7) { - /* - * During mash-out rest, allow the grain to sink - */ - if (set_MLT_pump(unit, unit->pump_mashout)) - syslog(LOG_NOTICE, "AUTO: mash-out turn %s MLT pump", mlt_pump_state ? "on":"off"); - } else { - if (set_MLT_pump(unit, unit->pump_onmash)) - syslog(LOG_NOTICE, "AUTO: mash turn %s MLT pump", mlt_pump_state ? "on":"off"); - } - brew->timeout--; - if (brew->timeout <= 0) { - syslog(LOG_NOTICE, "AUTO: mash step %d fase REST done", brew->mashstep); - if ((brew->mashstep == 0) && ! unit->skip_add) { - mash_fase = MASH_PROMPT; - } else if ((brew->mashstep == 6) && ! unit->skip_iodine) { - mash_fase = MASH_IODINE; - brew->timeout = unit->iodine_time * 60; - } else if (brew->mashstep == 7) { - mash_fase = MASH_DONE; - } else { - mash_fase = MASH_NA; - brew->mashstep++; - } - } - oldsec = seconds; - } - break; - - case MASH_DONE: syslog(LOG_NOTICE, "AUTO: mash step %d fase DONE", brew->mashstep); - if (set_MLT_heater(unit, 1, recipe->mash[7].setpoint)) - syslog(LOG_NOTICE, "AUTO: mash done turn MLT off"); - if (set_MLT_pump(unit, 0)) - syslog(LOG_NOTICE, "AUTO: mash done turn %s MLT pump", mlt_pump_state ? "on":"off"); - brew->mashstep = 0; - brew->brewstep = STEP_MASHREMOVE; - break; - } - break; - - case STEP_MASHREMOVE: if (unit->skip_remove) { - syslog(LOG_NOTICE, "AUTO: skipping Mash remove"); - brew->brewstep = STEP_PREBOIL; - } else { - if (brew->brewstep != last_step) { - prompt(118, NULL); /* "AUTO --> Mash Out " */ - prompt(220, NULL); /* " Mash Removed? " */ - prompt(300, NULL); - prompt(407, NULL); /* "--- --- No Yes " */ - last_step = brew->brewstep; - } - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_ENTER) { - syslog(LOG_NOTICE, "AUTO: Confirmed Mash removed"); - brew->brewstep = STEP_PREBOIL; - } - } - break; - - case STEP_PREBOIL: if (brew->brewstep != last_step) { - prompt(119, NULL); /* "AUTO --> Boil " */ - prompt(200, NULL); - prompt(300, NULL); - tempstatus(); - mltstatus(); - prompt(418, NULL); /* "--- --- Pause --- " */ - hlt_status(0); - mlt_status(1); - pump_status(unit->pump_onboil && (mltInput < unit->pump_stop)); - last_step = brew->brewstep; - } - if (oldsec != seconds) { - tempstatus(); - mltstatus(); - oldsec = seconds; - } - if (set_HLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: preboil turn off HLT"); - if (set_MLT_heater(unit, 1, 100.1)) - syslog(LOG_NOTICE, "AUTO: preboil turn on MLT to boil"); - if (set_MLT_pump(unit, unit->pump_onboil && (mltInput < unit->pump_stop))) - syslog(LOG_NOTICE, "AUTO: preboil turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (mltInput > 99.2) { - syslog(LOG_NOTICE, "AUTO: reached boil temperature %.2f, start %d minutes boil", mltInput, recipe->boiltime); - brew->brewstep = STEP_BOILING; - brew->boiltimer = recipe->boiltime * 60; - } - break; - - case STEP_BOILING: if (set_HLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: boil turn off HLT"); - if (set_MLT_heater(unit, 1, 100.1)) - syslog(LOG_NOTICE, "AUTO: boil turn on MLT to boil"); - if (set_MLT_pump(unit, unit->pump_onboil && (mltInput < unit->pump_stop))) - syslog(LOG_NOTICE, "AUTO: boil turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (brew->brewstep != last_step) { - prompt(119, NULL); /* "AUTO --> Boil " */ - prompt(200, NULL); - prompt(300, NULL); - tempstatus(); - mltstatus(); - prompt(418, NULL); /* "--- --- Pause --- " */ - hlt_status(0); - mlt_status(1); - pump_status(unit->pump_onboil && (mltInput < unit->pump_stop)); - last_step = brew->brewstep; - } - if (oldsec != seconds) { - tempstatus(); - if ((seconds / 2) % 4) { - timestatus(2, brew->boiltimer); - } else { - mltstatus(); - } - if (brew->boiltimer >= 0) { - brew->boiltimer--; - } else { - brew->brewstep = STEP_BOILDONE; - syslog(LOG_NOTICE, "AUTO: boil is done"); - } - oldsec = seconds; - } - break; - - case STEP_BOILDONE: if (set_MLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: after boil turn off MLT heater"); - if (set_MLT_pump(unit, 0)) - syslog(LOG_NOTICE, "AUTO: after boil turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (brew->brewstep != last_step) { - prompt(120, NULL); /* "AUTO --> Cooling " */ - prompt(214, NULL); /* " START COOLING " */ - prompt(300, NULL); - prompt(410, NULL); /* " Continue: Yes No " */ - last_step = brew->brewstep; - } - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_ENTER) { - brew->brewstep = STEP_CLEANUP; - syslog(LOG_NOTICE, "AUTO: user skipped cooling"); - } - if (key == KEY_RETURN) { - brew->brewstep = STEP_COOLING; - syslog(LOG_NOTICE, "AUTO: user started cooling"); - } - break; - - case STEP_COOLING: for (i = 0; i < 3; i++) { - if ((recipe->hopstand[i].skip == 0) && (mltInput <= recipe->hopstand[i].max) && (mltInput >= recipe->hopstand[i].min)) { - brew->brewstep = STEP_HOPSTAND; - hopstand = i; - syslog(LOG_NOTICE, "AUTO: starting hopstand %d", i+1); - } - } - if (brew->brewstep == STEP_HOPSTAND) - break; - // hot whirlpool start at 85 degrees - // cold whirlpool start at 30 degrees - - if (brew->brewstep != last_step) { - prompt(120, NULL); /* "AUTO --> Cooling " */ - prompt(200, NULL); - tempstatus(); - prompt(300, NULL); - prompt(418, NULL); /* "--- --- Pause --- " */ - hlt_status(0); - mlt_status(0); - pump_status(0); - last_step = brew->brewstep; - } - if (oldsec != seconds) { - tempstatus(); - oldsec = seconds; - } - if (mltInput <= recipe->coolto) { - syslog(LOG_NOTICE, "AUTO: cool temperture %.2f reached", recipe->coolto); - brew->brewstep = STEP_CLEANUP; - } - break; - - case STEP_HOPSTAND: if (brew->brewstep != last_step) { - prompt(122 + hopstand, NULL); /* "AUTO --> Hopstand n " */ - tempstatus(); - timestatus(2, brew->timeout); - prompt(418, NULL); /* "--- --- Pause --- " */ - brew->boiltimer = recipe->hopstand[hopstand].duration * 60; - last_step = brew->brewstep; - } - - if (recipe->hopstand[hopstand].hold) { - if (set_MLT_heater(unit, 1, recipe->hopstand[hopstand].setpoint)) - syslog(LOG_NOTICE, "AUTO: hopstand 1 turn on MLT at %6.2f", mltSetpoint); - } - if (set_MLT_pump(unit, 1)) - syslog(LOG_NOTICE, "AUTO: hopstand 1 turn %s MLT pump", mlt_pump_state ? "on":"off"); - if (oldsec != seconds) { - tempstatus(); - timestatus(2, brew->timeout); - brew->boiltimer--; - if (brew->boiltimer <= 0) { - syslog(LOG_NOTICE, "AUTO: hopstand %d done", hopstand+1); - if (set_MLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: hopstand 1 turn off MLT at %6.2f", mltSetpoint); - brew->brewstep = STEP_COOLING; - } - oldsec = seconds; - } - break; - - case STEP_WHIRLPOOL: prompt(121, NULL); /* "AUTO --> Whirlpool " */ - break; - - case STEP_CLEANUP: if (brew->brewstep != last_step) { - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(200, NULL); /* " " */ - prompt(300, NULL); /* " " */ - prompt(400, NULL); /* " " */ - last_step = brew->brewstep; - } - syslog(LOG_NOTICE, "AUTO: cleanup"); - if (set_HLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: cleanup turn on HLT at %6.2f", hltSetpoint); - if (set_MLT_heater(unit, 0, 10.0)) - syslog(LOG_NOTICE, "AUTO: cleanup turn on MLT at %6.2f", mltSetpoint); - if (set_MLT_pump(unit, 0)) - syslog(LOG_NOTICE, "AUTO: cleanup turn %s MLT pump", mlt_pump_state ? "on":"off"); - brew->brewstep = STEP_BREWDONE; - break; - - case STEP_BREWDONE: if (brew->brewstep != last_step) { - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(200, NULL); /* " " */ - prompt(301, NULL); /* " Finished " */ - prompt(408, NULL); /* "--- --- Ok --- " */ - last_step = brew->brewstep; - } - syslog(LOG_NOTICE, "AUTO: brew done"); - brew->brewstep = -1; - brew->endtime = time(NULL); - save = TRUE; - do { - key = keywait(); - } while (key != KEY_RETURN); - /* - * Rewrite the display - */ - prompt(101, NULL); /* " Brewco x.x.x " */ - tempstatus(); - prompt(300, NULL); /* " " */ - prompt(401, NULL); /* "--- MAN AUTO SETUP" */ - break; - } - - if (save) { - snprintf(data, 127, "%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f", brew->brewstep, - hltInput, hltOutput, hltSetpoint, mltInput, mltOutput, mltSetpoint); - logger(brew->name, data); - wrsession(brew); - } -} - - - -void manual_prompt(void) -{ - switch (manual) { - case MANUAL_SELHLT: prompt(104, NULL); /* " MANUAL MODE " */ - prompt(303, NULL); /* " Manual HLT " */ - prompt(402, NULL); /* "--- dwn quit ok " */ - break; - case MANUAL_SELMLT: prompt(104, NULL); /* " MANUAL MODE " */ - prompt(304, NULL); /* " Manual MLT " */ - prompt(404, NULL); /* " up --- quit ok " */ - break; - case MANUAL_HLT: prompt(104, NULL); /* " MANUAL MODE " */ - prompt(300, NULL); /* " " */ - prompt(413, NULL); /* "UP* *DWN heat --- " */ - break; - case MANUAL_MLT: prompt(104, NULL); /* " MANUAL MODE " */ - prompt(300, NULL); /* " " */ - prompt(406, NULL); /* "UP* *DWN heat pmp " */ - break; - } -} - - - -/* - * Manual menu for testing your equipment. - */ -int manual_menu(units_list *, int); -int manual_menu(units_list *unit, int seconds) -{ - int key; - - switch (manual) { - case MANUAL_SELHLT: slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_DOWN) { - manual = MANUAL_SELMLT; - manual_prompt(); - } - if (key == KEY_RETURN) { - manual = MANUAL_NONE; - mlt_pump_state = 0; - PID_setMode(unit->PID_mlt, P_MANUAL); - PID_setMode(unit->PID_hlt, P_MANUAL); - hlt_status(0); - mlt_status(0); - device_out(unit->mlt_pump.uuid, mlt_pump_state); - } - if (key == KEY_ENTER) { - // TODO: prompt for water - manual = MANUAL_HLT; - manual_prompt(); - } - break; - case MANUAL_SELMLT: slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_UP) { - manual = MANUAL_SELHLT; - manual_prompt(); - } - if (key == KEY_RETURN) { - manual = MANUAL_NONE; - mlt_pump_state = 0; - PID_setMode(unit->PID_mlt, P_MANUAL); - PID_setMode(unit->PID_hlt, P_MANUAL); - hlt_status(0); - mlt_status(0); - device_out(unit->mlt_pump.uuid, mlt_pump_state); - } - if (key == KEY_ENTER) { - // TODO: prompt for water - manual = MANUAL_MLT; - manual_prompt(); - } - break; - case MANUAL_HLT: tempstatus(); - percstatus((seconds / 2) % 4); - - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_RETURN) { - if (PID_getMode(unit->PID_hlt) == P_MANUAL) { - PID_setMode(unit->PID_hlt, P_AUTOMATIC); - hlt_status(1); - } else { - PID_setMode(unit->PID_hlt, P_MANUAL); - hlt_status(0); - } - } - if ((key == KEY_DOWN) && (hltSetpoint > 10)) - hltSetpoint -= 1.0; - if ((key == KEY_UP) && (hltSetpoint < 100)) - hltSetpoint += 1.0; - if (key == KEY_ESCAPE) { - manual = MANUAL_SELHLT; - manual_prompt(); - } - break; - case MANUAL_MLT: tempstatus(); - percstatus((seconds / 2) % 4); - - slcdDummy(slcdHandle); - key = keycheck(); - if (key == KEY_RETURN) { - if (PID_getMode(unit->PID_mlt) == P_MANUAL) { - PID_setMode(unit->PID_mlt, P_AUTOMATIC); - mlt_status(1); - } else { - PID_setMode(unit->PID_mlt, P_MANUAL); - mlt_status(0); - } - } - if ((key == KEY_DOWN) && (mltSetpoint > 10)) - mltSetpoint -= 1.0; - if ((key == KEY_UP) && (mltSetpoint < 100)) - mltSetpoint += 1.0; - if (key == KEY_ENTER) { - if (mlt_pump_state) - set_MLT_pump(unit, 0); - else - set_MLT_pump(unit, 1); - } - if (key == KEY_ESCAPE) { - manual = MANUAL_SELMLT; - manual_prompt(); - } - device_out(unit->mlt_pump.uuid, mlt_pump_state); - break; - } - - return 0; -} - - - -char *choose_recipe(void); -char *choose_recipe(void) -{ - int total, i, key, choice = 1; - static char uuid[37]; - a_recipe *recipe; - char pmpt[81]; - - strcpy(uuid, (char *)"00000000-0000-0000-0000-000000000000"); - for (;;) { - total = 0; - for (recipe = recipes; recipe; recipe = recipe->next) - total++; - - if (total == 0) - return uuid; - - i = 0; - for (recipe = recipes; recipe; recipe = recipe->next) { - i++; - if (i == choice) - break; - } - - prompt(102, NULL); /* " SETUP MENU " */ - prompt(221, NULL); /* " Select Recipe " */ - if (total) { - snprintf(pmpt, Config.lcd_cols + 1, "%s %s ", recipe->code, recipe->name); - prompt(300, pmpt); - } - if (total == 1) - prompt(405, NULL); /* "--- --- quit ok " */ - else if (choice == 1) - prompt(402, NULL); /* "--- dwn quit ok " */ - else if (choice == total) - prompt(404, NULL); /* " up --- quit ok " */ - else - prompt(403, NULL); /* " up dwn quit ok " */ - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) - return uuid; - if (key == KEY_ENTER) { - strcpy(uuid, recipe->uuid); - return uuid; - } - if ((key == KEY_UP) && (total > 1) && (choice > 1)) { - choice--; - } - if ((key == KEY_DOWN) && (total > 1) && (choice < total)) - choice++; - } -} - - - -int server(void); -int server(void) -{ - int rc = 0, run = 1, dosave, key, temp, MLTp, HLTp, percslot, percfase = PERC_INIT; - int do_init = TRUE, seconds = 0, minutes = 0; - units_list *unit; - a_recipe *recipe = NULL; - brew_session *brew = NULL; -#ifndef HAVE_WIRINGPI_H - long t = 0; -#endif - time_t now, last = (time_t)0; - long nowmillis, perctimer; - struct tm *tm; - - prompt(101, NULL); - - /* - * Define special characters in the display CGRAM - */ - if (Config.tempFormat == 'C') - slcdCharDef(slcdHandle, 1, degC); - else - slcdCharDef(slcdHandle, 1, degF); - slcdCharDef(slcdHandle, 2, SP_Symbol); - slcdCharDef(slcdHandle, 3, PumpONOFF); - slcdCharDef(slcdHandle, 4, RevPumpONOFF); - slcdCharDef(slcdHandle, 5, HeatONOFF); - slcdCharDef(slcdHandle, 6, RevHeatONOFF); - slcdCharDef(slcdHandle, 7, Language); - - if (lockprog((char *)"brewco")) { - syslog(LOG_NOTICE, "Can't lock"); - return 1; - } - - if (debug) - fprintf(stdout, "Begin server()\n"); - - if ((rc = devices_detect())) { - syslog(LOG_NOTICE, "Detected %d new devices", rc); - if (debug) - fprintf(stdout, "Detected %d new devices\n", rc); - wrconfig(); - } - -#ifdef HAVE_WIRINGPI_H - rc = piThreadCreate(my_devices_loop); -#else - rc = pthread_create(&threads[t], NULL, my_devices_loop, (void *)t ); -#endif - if (rc) { - fprintf(stderr, "my_devices_loop thread didn't start rc=%d\n", rc); - syslog(LOG_NOTICE, "my_devices_loop thread didn't start rc=%d", rc); -#ifndef HAVE_WIRINGPI_H - } else { - t++; -#endif - } - -#ifdef HAVE_WIRINGPI_H - rc = piThreadCreate(my_keyboard_loop); -#else - rc = pthread_create(&threads[t], NULL, my_keyboard_loop, (void *)t ); -#endif - if (rc) { - fprintf(stderr, "my_keyboard_loop thread didn't start rc=%d\n", rc); - syslog(LOG_NOTICE, "my_keyboard_loop thread didn't start rc=%d", rc); -#ifndef HAVE_WIRINGPI_H - } else { - t++; -#endif - } - -#ifdef USE_SIMULATOR -#ifdef HAVE_WIRINGPI_H - rc = piThreadCreate(my_simulator_loop); -#else - rc = pthread_create(&threads[t], NULL, my_simulator_loop, (void *)t ); -#endif - if (rc) { - fprintf(stderr, "my_simulator_loop thread didn't start rc=%d\n", rc); - syslog(LOG_NOTICE, "my_simulator_loop thread didn't start rc=%d", rc); -#ifndef HAVE_WIRINGPI_H - } else { - t++; -#endif - } -#endif - - if (! Config.units) { - /* - * No brewsystems defined, add the first - */ - prompt(218, NULL); /* Add Brewsystem? */ - prompt(407, NULL); /* --- --- Ok --- */ - - do { - key = keywait(); - } while (key != KEY_RETURN); - - if (key == KEY_RETURN) { - addUnit(1); - } - } - - /* - * Initialize units for processing - */ - for (unit = Config.units; unit; unit = unit->next) { - if (unit->active) - break; - } - - if (! unit->active) { - fprintf(stdout, "No active units found\n"); - } - - /* - * Safety, turn everything off - */ - if (unit->active) { - if (debug) - fprintf(stdout, "Starting brewsystem %d `%s'\n", unit->number, unit->name); - syslog(LOG_NOTICE, "Starting brewsystem %d `%s'", unit->number, unit->name); - } - - /* - * During automation there will be a state file: - * ~/.brewco/var/brewing.xml - * If this file is present, there has been a crash. - */ - brew = (brew_session *)malloc(sizeof(brew_session)); - rc = rdsession(brew); - syslog(LOG_NOTICE, "rdsession: rc=%d", rc); - if (debug) - fprintf(stdout, "rdsession: rc=%d\n", rc); - - char *mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"brewing.xml"); - if (rc == 0) { - if (debug) - fprintf(stdout, "Active brew session found\n"); - } else if (rc == -1) { - free(brew); - brew = NULL; - if (debug) - fprintf(stdout, "No active brew session found\n"); - } else { - unlink(mypath); - free(brew); - brew = NULL; - if (debug) - fprintf(stdout, "Error brew session found\n"); - } - free(mypath); - mypath = NULL; - - do { - if (my_shutdown) { - run = 0; - unit->hlt_heater.value = 0; - unit->mlt_heater.value = 0; - unit->mlt_pump.value = 0; - device_out(unit->hlt_heater.uuid, 0); - device_out(unit->mlt_heater.uuid, 0); - device_out(unit->mlt_pump.uuid, 0); - hlt_status(0); - mlt_status(0); - break; - } - - /* - * Do we need to initialize this unit? - */ - if (do_init) { - if (debug) - fprintf(stdout, "Initialize brewsystem %d `%s'\n", unit->number, unit->name); - syslog(LOG_NOTICE, "Initialize brewsystem %d `%s'", unit->number, unit->name); - - prompt(0, NULL); - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(401, NULL); /* "--- MAN AUTO SETUP" */ - - /* - * Turn everything off - */ - unit->hlt_heater.value = 0; - unit->mlt_heater.value = 0; - unit->mlt_pump.value = 0; - device_out(unit->hlt_heater.uuid, 0); - device_out(unit->mlt_heater.uuid, 0); - device_out(unit->mlt_pump.uuid, 0); - - /* - * Initialize PID's - */ - hltInput = hltSetpoint = mltInput = mltSetpoint = 20.0; - hltOutput = mltOutput = 0; - PID_init(unit->PID_hlt, &hltInput, &hltOutput, &hltSetpoint, unit->PID_hlt->dispKp, unit->PID_hlt->dispKi, unit->PID_hlt->dispKd, unit->PID_hlt->Direction); - PID_setOutputLimits(unit->PID_hlt, 0, 100); - PID_setSampleTime(unit->PID_hlt, unit->PID_hlt->SampleTime); - PID_init(unit->PID_mlt, &mltInput, &mltOutput, &mltSetpoint, unit->PID_mlt->dispKp, unit->PID_mlt->dispKi, unit->PID_mlt->dispKd, unit->PID_mlt->Direction); - PID_setOutputLimits(unit->PID_mlt, 0, 100); - PID_setSampleTime(unit->PID_mlt, unit->PID_mlt->SampleTime); - hlt_status(0); - mlt_status(0); - - manual = MANUAL_NONE; - - do_init = FALSE; - nowmillis = perctimer = millis(); - percslot = 0; - percfase = PERC_INIT; - dosave = 0; - - if (brew) { - /* - * Restore session - */ - if (debug) - fprintf(stdout, "loop_init: restoring brew session\n"); - for (recipe = recipes; recipe; recipe = recipe->next) { - if (strcmp(recipe->uuid, brew->uuid_recipe) == 0) { - break; - } - } - if (debug) - fprintf(stdout, "loop_init: brewstep=%d mashstep=%d recipe=%s\n", brew->brewstep, brew->mashstep, recipe->code); - } - } - - /* run_pause code here */ - - /* - * Update PID's, even if they are off. Both PID's will do - * the scheduling by themselves. - */ - rc = PID_compute(unit->PID_hlt); - rc = PID_compute(unit->PID_mlt); - - /* - * This is the serial heaters schedule loop. The total - * loop time is 5 seconds, heating is 0..100% so we - * have 5 mSeconds timeslots. The MLT has priority over - * the HLT heater, so the HLT heater can get too little - * power. TODO: simultaneous use must be implemented. - * In sequentiel mode, the total drawn power is the same - * as the power used by the largest heater element. - */ - nowmillis = millis(); - if (nowmillis > (perctimer + 50)) { - percslot++; - if (percfase == PERC_INIT) { - HLTp = (int)hltOutput; - MLTp = (int)mltOutput; - if ((MLTp + HLTp) > 100) - HLTp = 100 - MLTp; /* The HLT has lower priority */ - if (MLTp) { - percfase = PERC_MLT; - device_out(unit->hlt_heater.uuid, 0); - device_out(unit->mlt_heater.uuid, 1); - } else if (HLTp) { - percfase = PERC_HLT; - device_out(unit->hlt_heater.uuid, 1); - device_out(unit->mlt_heater.uuid, 0); - } else { - percfase = PERC_REST; - device_out(unit->hlt_heater.uuid, 0); - device_out(unit->mlt_heater.uuid, 0); - } -// if (debug) -// fprintf(stdout, " perslot=%d MLT=%d%% HLT=%d%% fase=%d\n", percslot, MLTp, HLTp, percfase); - } else if (percfase == PERC_MLT) { - if (percslot > MLTp) { - device_out(unit->mlt_heater.uuid, 0); - if (HLTp) { - device_out(unit->hlt_heater.uuid, 1); - percfase = PERC_HLT; - } else { - percfase = PERC_REST; - } - } - } else if (percfase == PERC_HLT) { - if (percslot > (MLTp + HLTp)) { - device_out(unit->hlt_heater.uuid, 0); - percfase = PERC_REST; - } - } - if (percslot == 100) { /* End of the loop, start over */ - percslot = 0; - percfase = PERC_INIT; - } - perctimer = nowmillis; - } - - now = time(NULL); - if (now != last) { - /* - * Each second - */ - last = now; - seconds++; - - if (seconds > 59) { - seconds = 0; - minutes++; - dosave = 1; - } - - rc = device_in(unit->hlt_sensor.uuid, &temp); - if (rc == DEVPRESENT_YES) { - hltInput = temp / 1000.0; - unit->hlt_sensor.state = 0; - } else if (rc == DEVPRESENT_ERROR) { - unit->hlt_sensor.state = 1; - } else { - unit->hlt_sensor.state = 2; - } - rc = device_in(unit->mlt_sensor.uuid, &temp); - if (rc == DEVPRESENT_YES) { - mltInput = temp / 1000.0; - unit->mlt_sensor.state = 0; - } else if (rc == DEVPRESENT_ERROR) { - unit->mlt_sensor.state = 1; - } else { - unit->mlt_sensor.state = 2; - } - - if (debug && ((seconds % 10) == 1)) { - fprintf(stdout, "MLT: In=%.2lf Out=%.2lf Set=%.2lf Stat=%d HLT: In=%.2lf Out=%.2lf Set=%.2lf Stat=%d\n", - mltInput, mltOutput, mltSetpoint, PID_getMode(unit->PID_mlt), - hltInput, hltOutput, hltSetpoint, PID_getMode(unit->PID_hlt)); - } - - } - - if (brew) { - /* - * Automate mode - */ - automatic_brew(unit, brew, recipe, dosave, seconds); - dosave = 0; - if (brew->brewstep == -1) { - /* - * Save session and move it - */ - wrsession(brew); - char *fpath, *tpath; - fpath = xstrcpy(etcpath); - fpath = xstrcat(fpath, (char *)"brewing.xml"); - tpath = xstrcpy(varpath); - tpath = xstrcat(tpath, (char *)"old/brewing.xml."); - mkdirs(tpath, 0755); - tpath = xstrcat(tpath, brew->name); - if (debug) - fprintf(stdout, "auto: saving as %s\n", tpath); - file_cp(fpath, tpath); - unlink(fpath); - free(fpath); - free(tpath); - - /* - * Free memory, session is over. - */ - if (brew->name) - free(brew->name); - if (brew->uuid_recipe) - free(brew->uuid_recipe); - if (brew->uuid_unit) - free(brew->uuid_unit); - free(brew); - brew = NULL; - } - - } else if (manual != MANUAL_NONE) { - /* - * Manual mode - */ - manual_menu(unit, seconds); - if (manual == MANUAL_NONE) { - /* - * Rewrite the display - */ - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(300, NULL); /* " " */ - prompt(401, NULL); /* "--- MAN AUTO SETUP" */ - } - } else { - /* - * Not running. - */ - tempstatus(); - key = keycheck(); - if (key == KEY_ENTER) { - setup(); - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(200, NULL); - prompt(300, NULL); - hlt_status(0); - mlt_status(0); - pump_status(0); - prompt(401, NULL); /* "--- MAN AUTO SETUP" */ - } else if (key == KEY_RETURN && ! brew) { - int i, isOk = TRUE; - char message[41]; - - tm = localtime(&now); - 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); - brew = (brew_session *)malloc(sizeof(brew_session)); - brew->uuid_recipe = xstrcpy(choose_recipe()); - brew->uuid_unit = xstrcpy(unit->uuid); - brew->name = xstrcpy(message); - brew->brewstep = STEP_NA; - brew->mashstep = MASH_NA; - brew->timeout = brew->boiltimer = 0; - brew->starttime = brew->endtime = (time_t)0; - /* - * Now check if everything is sane - */ - if (strcmp(brew->uuid_recipe, (char *)"00000000-0000-0000-0000-000000000000") == 0) { - isOk = FALSE; - snprintf(message, Config.lcd_cols + 1, " No recipe selected "); - if (debug) - fprintf(stdout, "brew init: No recipe selected\n"); - } - if (isOk) { - isOk = FALSE; - for (recipe = recipes; recipe; recipe = recipe->next) { - if (strcmp(recipe->uuid, brew->uuid_recipe) == 0) { - isOk = TRUE; - if (! recipe->boiltime) - isOk = FALSE; - for (i = 0; i < 8; i++) { - if (! recipe->mash[i].skip && ! recipe->mash[i].setpoint) - isOk = FALSE; - } - for (i = 0; i < 3; i++) { - if (! recipe->hopstand[i].skip && recipe->hopstand[i].hold && (recipe->hopstand[i].setpoint == 0)) - isOk = FALSE; - } - break; - } - } - if (isOk == FALSE) { - snprintf(message, Config.lcd_cols + 1, " Recipe error "); - if (debug) - fprintf(stdout, "brew init: recipe error\n"); - } - } - - if (debug) - fprintf(stdout, "init brew: %s\n", isOk ? (char *)"Ok":(char *)"Error"); - - if (isOk) { - wrsession(brew); - } else { - prompt(300, message); - prompt(408, NULL); /* "--- --- Ok --- " */ - key = keywait(); - if (brew->name) - free(brew->name); - if (brew->uuid_recipe) - free(brew->uuid_recipe); - if (brew->uuid_unit) - free(brew->uuid_unit); - free(brew); - brew = NULL; - /* - * Rewrite the display - */ - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(300, NULL); /* " " */ - prompt(401, NULL); /* "--- MAN AUTO SETUP" */ - } - - } else if (key == KEY_DOWN) { - manual = MANUAL_SELHLT; - manual_prompt(); - } - } - - usleep(5000); /* 5 mSec */ - - } while (run); - - syslog(LOG_NOTICE, "Out of loop"); - if (debug) - fprintf(stdout, (char *)"Out of loop\n"); - - prompt(0, NULL); - prompt(101, NULL); /* " Brewco x.x.x " */ - prompt(302, NULL); /* " Shutting down " */ - - /* - * Give threads time to cleanup - */ - usleep(1500000); - prompt(0, NULL); - setBacklight(0); - - if (sock != -1) { - if (shutdown(sock, SHUT_RDWR)) { - syslog(LOG_NOTICE, "Can't shutdown socket: %s", strerror(errno)); - } - sock = -1; - } - - wrrecipes(); - wrconfig(); - ulockprog((char *)"brewco"); - return 0; -} - - - -int main(int argc, char *argv[]) -{ - int rc = 0, c, i; - char *homepath = NULL; - - while (1) { - int option_index = 0; - static struct option long_options[] = { - {"debug", 0, 0, 'c'}, - {"help", 0, 0, 'h'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "dh", long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'd': debug = TRUE; - break; - case 'h': help(); - return 1; - } - } - - openlog("brewco", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); - syslog(LOG_NOTICE, "mbsePi-apps brewco v%s starting", VERSION); - if (debug) - fprintf(stdout, "mbsePi-apps brewco v%s starting\n", VERSION); - - /* - * Set home directory path - */ - if (getenv((char *)"USER") == NULL) { - homepath = xstrcpy((char *)"/root"); - } else { - homepath = xstrcpy(getenv((char *)"HOME")); - } - varpath = xstrcpy(homepath); - varpath = xstrcat(varpath, (char *)"/.brewco/var/"); - etcpath = xstrcpy(homepath); - etcpath = xstrcat(etcpath, (char *)"/.brewco/etc/"); - mkdirs(varpath, 0755); - mkdirs(etcpath, 0755); - - if (rdconfig()) { - fprintf(stderr, "Error reading configuration\n"); - syslog(LOG_NOTICE, "Error reading configuration: halted"); - return 1; - } - if (debug) - fprintf(stdout, "configuration loaded\n"); - - if (rdrecipes()) { - fprintf(stderr, "Error reading recipes\n"); - syslog(LOG_NOTICE, "Error reading recipes: halted"); - return 1; - } - if (debug) - fprintf(stdout, "recipes loaded\n"); - - /* - * Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored - * but that's live. This daemon should only be stopped by SIGTERM. - * Don't catch SIGCHLD. - */ - for (i = 0; i < NSIG; i++) { - if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) - signal(i, (void (*))die); - } - -#ifdef HAVE_WIRINGPI_H - if (wiringPiSetup () ) - return 1; -#endif - - if ((rc = initLCD (Config.lcd_cols, Config.lcd_rows))) { - fprintf(stderr, "Cannot initialize LCD display, rc=%d\n", rc); - return 1; - } - - rc = server(); - - syslog(LOG_NOTICE, "Finished, rc=%d", rc); - if (debug) - fprintf(stdout, "Finished, rc=%d\n", rc); - return rc; -} - -