# HG changeset patch # User Michiel Broek # Date 1456438486 -3600 # Node ID d5bc44183aa45fc858a961baac16141bb5df94c7 # Parent 5a237a99a793e5eed7fffb66fb2743d5c961037f Bumped to version 0.5.2 and removed the brewco subdirectory because that has been implemented as Arduino project. diff -r 5a237a99a793 -r d5bc44183aa4 brewco/Makefile --- a/brewco/Makefile Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -# Makefile for the mbsePi-apps/brewco. - -include ../Makefile.global - -SRCS = $(wildcard *.c) -HDRS = $(wildcard *.h) -OBJS = $(SRCS:.c=.o) -SLIBS = -lpthread -lz -lrt -TARGET = brewco -OTHER = Makefile - -############################################################################# - -.c.o: - ${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $< - -all: ${TARGET} - -brewco: ${OBJS} ${SLIBS} - ${CC} -o brewco ${OBJS} ${LDFLAGS} ${LIBS} ${SLIBS} - -clean: - rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak - -install: all - ${INSTALL} -c -s -g root -o root -m 0755 brewco ${BINDIR} - -filelist: Makefile - BASE=`pwd`; \ - BASE=`basename $${BASE}`; \ - (for f in ${SRCS} ${HDRS} ${OTHER} ;do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist - -depend: - @rm -f Makefile.bak; \ - mv Makefile Makefile.bak; \ - sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \ - ${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \ - >>Makefile; \ - ${ECHO} '# Dependencies generated by make depend' >>Makefile; \ - for f in ${SRCS}; \ - do \ - ${ECHO} "Dependencies for $$f:\c"; \ - ${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \ - for h in `sed -n -e \ - 's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \ - do \ - ${ECHO} " $$h\c"; \ - ${ECHO} " $$h\c" >>Makefile; \ - done; \ - ${ECHO} " done."; \ - ${ECHO} "" >>Makefile; \ - done; \ - ${ECHO} '# End of generated dependencies' >>Makefile - -# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT -# Dependencies generated by make depend -rdrecipes.o: brewco.h rdrecipes.h util.h xutil.h -setup.o: brewco.h slcd.h setup.h prompt.h xutil.h keyboard.h rdconfig.h rdrecipes.h -devices.o: brewco.h devices.h util.h xutil.h keyboard.h slcd.h -xutil.o: brewco.h xutil.h -brewco.o: brewco.h rdconfig.h rdsession.h rdrecipes.h util.h xutil.h lcd-pcf8574.h slcd.h lock.h devices.h keyboard.h simulator.h prompt.h setup.h logger.h -lock.o: lock.h brewco.h -logger.o: logger.h brewco.h util.h xutil.h -lcd-pcf8574.o: brewco.h lcd-pcf8574.h slcd.h -pid.o: brewco.h pid.h util.h -util.o: brewco.h util.h slcd.h -keyboard.o: brewco.h lcd-pcf8574.h slcd.h keyboard.h -simulator.o: brewco.h simulator.h -rdconfig.o: rdconfig.h brewco.h util.h xutil.h -rdsession.o: brewco.h rdsession.h util.h xutil.h -slcd.o: brewco.h slcd.h util.h xutil.h -prompt.o: brewco.h slcd.h prompt.h -# End of generated dependencies diff -r 5a237a99a793 -r d5bc44183aa4 brewco/README --- a/brewco/README Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ - Testplan. - --------- - -1. Start a brew, delay start = yes. Set a delay. - Ack water added. See Pump Prime. Then see the - delay countdown. After timeout, mash-in starts. - -2. Start a brew, delay start = no. Ack water added. - See pump prime. Then mash-in should start. - -3. Start a brew, delay start = no. Nack water added. - Brew should cleanup and finish. - -4. Start a brew, delay start = no. Ack water added. - See pump prime. Then mash-in should start. - If set for Skip-add mashing should start. - -5. Start a brew, delay start = no. Ack water added. - See pump prime. Then mash-in should start. - If not Skip-add, should ask for Mash added. - If Nack, brew should cleanup and finish. - -6. Start a brew, delay start = no. Ack water added. - See pump prime. Then mash-in should start. - If not Skip-add, should ask for Mash added. - If Ack, mashing should start. - - - -Intern temperatuur in Celcius, float 3 cijfers achter comma. -Als het systeem in Farenheid mode staat is alleen de -presentatie in Farenheid. - -Er moeten meerdere installaties in. -Iedere installatie heeft een MLT/brew kettle. -Optie HLT. -Keuze pomp/roeren. Keuze PWM/On-off. - -Default start, kies installatie. Tenzij een programma loopt (na een crash) -start laatst gekozen installatie. - -Extra t.o.v. ArdBir: hopstands. -1. 88..100 graden, 93 graden hold. -2. 72..77 graden -3. 60..66 graden -Inbouwn in Cooling. Timings: 1..4 uur. - - -Menus: - -Buttons: Up Down Start Enter - -12345678901234567890 --------------------- -Open ArdBir 2.8.3 (lang) - 22.50 C - ---- MAN AUTO SETUP --------------------- - SETUP MENU - PID -- PWM - - --- dwn quit ok --------------------- - SETUP MENU - Unit Parameters - - up dwn quit ok --------------------- - SETUP MENU - Set Automation - - up dwn quit ok --------------------- - SETUP MENU - Manage Recipes - - up dwn quit ok --------------------- - SETUP MENU - 22.50C 35.50sp -R 0:00:00 P - UP* *DWN heat pmp --------------------- - AUTOMATIC MODE - Delay start? - - --- --- No Yes --------------------- - AUTOMATIC MODE - Resume Process - - Continue: Yes No --------------------- - AUTOMATIC MODE - Water Added? - - Continue: Yes No --------------------- - AUTOMATIC MODE - Pump Prime - P - --------------------- -AUTO --> Mash In - 36.50C 36.50sp -R P - UP* *DWN Pause --- --------------------- - AUTOMATIC MODE - Setting Delay - 00:15:00 - Continue: Yes No --------------------- - AUTOMATIC MODE - To be started in - 00:13:58 - --------------------- -AUTO --> Mash In - 36.50C 36.50sp - Temp reached P - Continue: Yes --- --------------------- -AUTO --> Mash In - 36.50C 36.50sp -R Add Mash P - Continue: Yes No --------------------- ------ 72.00c ----- - Iodine test - 00:01:33 - --- --- Ok --- --------------------- -AUTO --> Mash Out - 78.00c 78.00sp -R Remove Malt P - Continue: Yes No --------------------- -AUTO --> Hop xx - 98.00c 98.00sp -RPWM= 85% 01:00:00P - UP* *DWN Pause --- --------------------- - - START COOLING - - Continue: Yes No --------------------- -AUTO --> Cooling - 93.00c 21.00sp - P - UP* *DWN --- pmp --------------------- - - WHIRLPOOL - - Continue: Yes No --------------------- - - Timing Whirlpool - 00:03:00 - Up Dwn Exit Ok --------------------- - - Brewing Process - Finished - --------------------- - 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; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/brewco.h --- a/brewco/brewco.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,324 +0,0 @@ -#ifndef _BREWCO_H -#define _BREWCO_H - -#define TRUE 1 -#define FALSE 0 - -#include "../config.h" -#include "pid.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef HAVE_WIRINGPI_H -#include -#endif -#include -#include -#include -#include - -#ifdef HAVE_WIRINGPI_H -/* wiringPi */ -#include -#include -#include - -/* - * Thread locks - */ -#define LOCK_DEVICES 0 -#define LOCK_LCD 1 -#define LOCK_MENU 2 -#define LOCK_SPARE2 3 - - -#endif - -/* - * 1-Wire devices - */ -#define W1_FAMILY_DEFAULT 0 -#define W1_FAMILY_SMEM_01 0x01 -#define W1_FAMILY_SMEM_81 0x81 -#define W1_THERM_DS18S20 0x10 -#define W1_FAMILY_DS28E04 0x1C -#define W1_COUNTER_DS2423 0x1D -#define W1_THERM_DS1822 0x22 -#define W1_EEPROM_DS2433 0x23 -#define W1_THERM_DS18B20 0x28 -#define W1_FAMILY_DS2408 0x29 -#define W1_EEPROM_DS2431 0x2D -#define W1_FAMILY_DS2760 0x30 -#define W1_FAMILY_DS2780 0x32 -#define W1_FAMILY_DS2413 0x3A -#define W1_THERM_DS1825 0x3B -#define W1_FAMILY_DS2781 0x3D -#define W1_THERM_DS28EA00 0x42 - - -#define MBSE_SS(x) (x)?(x):"(null)" - - - - -/* - * Sensor strcuture - */ -typedef struct _sensor_var { - char *uuid; /* sensor uuid */ - int state; /* sensor state */ - int value; /* sensor value */ -} sensor_var; - - - -/* - * Switch structure - */ -typedef struct _switch_var { - char *uuid; /* switch uuid */ - int value; /* switch value (0..100) */ - int delay; /* switch delay */ -} switch_var; - - - -/* - * Brewing units. The sensors of the units are connected via the 1-wire bus. - * The heaters, pumps (or mixer) are connected on the Pi GPIO. The hardware - * is configured in the devices lists. - */ -typedef struct _units_list { - struct _units_list *next; - int version; /* Record version */ - char *uuid; /* uuid code */ - char *name; /* Unit name */ - int number; /* Unit number */ - int active; /* 0/1 active unit */ - sensor_var hlt_sensor; /* HLT sensor */ - switch_var hlt_heater; /* HLT heater */ - int hlt_heater_mltfirst; /* HLT heater MLT high priority */ - sensor_var mlt_sensor; /* MLT sensor */ - switch_var mlt_heater; /* MLT heater */ - switch_var mlt_pump; /* MLT pump */ - int pump_cycle; /* 5..15 minutes */ - int pump_rest; /* 1..5 minutes */ - int pump_premash; /* 0/1 */ - int pump_onmash; /* 0/1 */ - int pump_mashout; /* 0/1 */ - int pump_onboil; /* 0/1 pump during boiling */ - float pump_stop; /* 80..105 C */ - int skip_add; /* 0/1 skip Add phase */ - int skip_remove; /* 0/1 skip Remove phase */ - int skip_iodine; /* 0/1 skip Iodine test */ - int iodine_time; /* 0..90 minutes */ - int whirlpool; /* off/cold/hot */ - pid_var *PID_hlt; /* HLT PID */ - pid_var *PID_mlt; /* MLT PID */ -} units_list; - - - -/* - * External devices like sensors, relays, SSR. - */ -typedef struct _dev_list { - struct _dev_list *next; - int version; /* Version 1 */ - char *uuid; /* UUID of this device */ - int type; /* Device type */ - int direction; /* Device direction */ - int value; /* Device value */ - int offset; /* Device offset value */ - int present; /* Device present */ - char *address; /* Device address */ - int subdevice; /* Device sub address */ - int gpiopin; /* Device GPIO pin or -1 */ - char *description; /* Device description */ - int inuse; /* In use counter */ - char *comment; /* What we think it is */ - time_t timestamp; /* Last updated */ -} devices_list; - - -#define DEVTYPE_NA 0 /* Unknown device type */ -#define DEVTYPE_W1 1 /* 1-Wire bus */ -#define DEVTYPE_GPIO 2 /* GPIO I/O device */ -#define DEVTYPE_I2C 3 /* I2C bus device */ -#define DEVTYPE_SPI 4 /* SPI bus device */ -#ifdef USE_SIMULATOR -#define DEVTYPE_SIM 5 /* Simulated device */ -#endif - -#define DEVPRESENT_UNDEF 0 /* Precence not testable */ -#define DEVPRESENT_NO 1 /* Device is missing */ -#define DEVPRESENT_YES 2 /* Device is detected */ -#define DEVPRESENT_ERROR 3 /* Device is in error */ - -#define DEVDIR_UNDEF 0 /* Undefined */ -#define DEVDIR_IN_BIN 1 /* Binary input */ -#define DEVDIR_OUT_BIN 2 /* Binary output */ -#define DEVDIR_IN_ANALOG 3 /* Temperature input etc. */ -#define DEVDIR_OUT_ANALOG 4 /* Analog steering */ -#define DEVDIR_OUT_PWM 5 /* PWM outout */ -#define DEVDIR_INTERN 6 /* Internal function */ - - - -/* - * Recipes. - */ -typedef struct _mash_step { - char *name; /* Step name */ - int min; /* Minimum temperature */ - int max; /* Maximum temperature */ - int canskip; /* 0/1 can we skip this step */ - float setpoint; /* Temperature setpoint */ - int skip; /* Skip this step */ - int duration; /* Step duration */ -} mash_step; - -typedef struct _hop_stand { - char *name; /* Hop stand name */ - int min; /* Minimum temperature */ - int max; /* Maximum temperature */ - int hold; /* Hold temperature at */ - float setpoint; /* Hold temperature setpoint */ - int skip; /* Skip this one */ - int duration; /* Hold time */ -} hop_stand; - -typedef struct _hop_addition { - char *name; /* Hop name */ - int skip; /* Skip addition */ - int boiltime; /* -1=fwh, 0..boiltime */ -} hop_addition; - -typedef struct _a_recipe { - struct _a_recipe *next; - char *uuid; /* Recipe uuid */ - char *code; /* Recipe code */ - char *name; /* Recipe name */ - int boiltime; /* 1..240 minutes */ - float coolto; /* Cooling target */ - time_t starttime; /* Start time */ - time_t endtime; /* Ending time */ - mash_step mash[8]; /* 8 mash steps */ - hop_addition hops[10]; /* 10 hop additions */ - hop_stand hopstand[3]; /* 3 hopstand slots */ -} a_recipe; - - - - -#ifdef USE_SIMULATOR - -/* - * Simulate a HLT and MLT. - */ -typedef struct _simulator { - double room_temperature; /* Simulated envionment temp */ - double hlt_temperature; /* Simulated HLT temperature */ - double hlt_heater_temp; /* Maximum heater temp */ - int hlt_heater_volume; /* Water volume */ - int hlt_heater_power; /* Power of the heater */ - int hlt_heater_state; /* Heater status */ - double mlt_temperature; /* Simulated MLT temperature */ - double mlt_heater_temp; /* Maximum heater temp */ - int mlt_heater_volume; /* Water volume */ - int mlt_heater_power; /* Power of the heater */ - int mlt_heater_state; /* Heater status */ -} simulator_var; - -#endif - - - -typedef struct _sys_config { - char *name; /* Configuration name */ - int my_port; /* my client/server port */ - unsigned char tempFormat; /* Temperature format, C or F */ - sensor_var *roomtemp; /* Environment temperature */ - int lcd_cols; /* LCD display columns */ - int lcd_rows; /* LCD display rows */ - int lcd_address; /* LCD display i2c address */ - units_list *units; /* Brewing units */ - devices_list *devices; /* Sensors and switches */ -#ifdef USE_SIMULATOR - simulator_var *simulator; /* Simulator */ -#endif -} sys_config; - - - -/* - * Brewing state file ~/.brewco/var/brewing.xml - * If present a brew session is running - */ -#define STEP_NA 0 /* Not in any step yet */ -#define STEP_BREWINIT 1 /* Initialize brew */ -#define STEP_WATERCHECK 2 /* Water added? */ -#define STEP_PUMPPRIME 3 /* Pump Prime */ -#define STEP_WAITSTART 4 /* Wait for starttime */ -#define STEP_PREMASH 5 /* Pre-mash */ -#define STEP_MASHING 6 /* Mash steps */ -#define STEP_MASHREMOVE 7 /* Remove mash */ -#define STEP_PREBOIL 8 /* Heating before boil */ -#define STEP_BOILING 9 /* Boil */ -#define STEP_BOILDONE 10 /* Boil done, hopstand */ -#define STEP_COOLING 11 /* Cooling */ -#define STEP_HOPSTAND 12 /* Hopstand */ -#define STEP_WHIRLPOOL 13 /* Final whirlpool */ -#define STEP_CLEANUP 14 /* Cleanup */ -#define STEP_BREWDONE 15 /* Final step */ - -#define MASH_NA 0 /* Not in any state yet */ -#define MASH_PROMPT 1 /* Prompt for mash */ -#define MASH_IODINE 2 /* Prompt for iodine test */ -#define MASH_HEATING 3 /* Heating phase */ -#define MASH_REST 4 /* Rest phase */ -#define MASH_DONE 5 /* This step is done */ - - - -typedef struct _brew_session { - char *uuid_recipe; /* Brewing this recipe */ - char *uuid_unit; /* Brewing unit */ - char *name; /* Session name */ - int brewstep; /* Main steps */ - int mashstep; /* Mash step */ - int timeout; /* Generic time downcouner */ - int boiltimer; /* Boiling downcount */ - time_t starttime; /* Start of brew */ - time_t endtime; /* End of brew */ -} brew_session; - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/devices.c --- a/brewco/devices.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,848 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014..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 "devices.h" -#include "util.h" -#include "xutil.h" -#include "keyboard.h" -#include "slcd.h" - - -extern int debug; -extern sys_config Config; -extern int my_shutdown; -extern uint16_t leds; -extern int slcdHandle; - -#ifdef USE_SIMULATOR - -extern int SIM_hlt_value; -extern int SIM_mlt_value; - -#endif - - - -/* - * Read one byte from a 1-wire device like a DS2413 - */ -int read_w1(char *address, char *file) -{ - char *addr = NULL; - int fn = -1, rc = -1, retries = 5; - uint8_t val; - - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, address); - addr = xstrcat(addr, (char *)"/"); - addr = xstrcat(addr, file); - - if ((fn = open(addr, O_RDONLY)) >= 0) { - - if ((lseek(fn, 0L, SEEK_SET)) == 0) { - - while (retries--) { - if ((read(fn, &val, 1)) == 1) { - rc = (int)val; - goto leave; - } - } - syslog(LOG_NOTICE, "read_w1() read %s fatal: %s", addr, strerror(errno)); - - } else { - syslog(LOG_NOTICE, "read_w1() lseek %s: %s", addr, strerror(errno)); - } - - } else { - syslog(LOG_NOTICE, "read_w1() open %s: %s", addr, strerror(errno)); - } - -leave: - if (fn != -1) { - if ((close(fn)) == -1) { - syslog(LOG_NOTICE, "read_w1() close %s: %s", addr, strerror(errno)); - } - } - - free(addr); - return rc; -} - - - -/* - * Write a byte to a 1-wire device like a DS2413 - */ -int write_w1(char *address, char *file, uint8_t val) -{ - char *addr = NULL; - int fn = -1, rc = -1, retries = 5; - - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, address); - addr = xstrcat(addr, (char *)"/"); - addr = xstrcat(addr, file); - - if ((fn = open(addr, O_WRONLY)) >= 0) { - - if ((lseek(fn, 0L, SEEK_SET)) == 0) { - - while (retries--) { - if ((write(fn, &val, 1)) == 1) { - rc = 0; - goto leave; - } - } - syslog(LOG_NOTICE, "write_w1() write %s fatal: %s", addr, strerror(errno)); - - } else { - syslog(LOG_NOTICE, "write_w1() lseek %s: %s", addr, strerror(errno)); - } - - } else { - syslog(LOG_NOTICE, "write_w1() open %s: %s", addr, strerror(errno)); - } - -leave: - if (fn != -1) { - if ((close(fn)) == -1) { - syslog(LOG_NOTICE, "write_w1() close %s: %s", addr, strerror(errno)); - } - } - - free(addr); - return rc; -} - - - -void hlt_heater(int value) -{ - if (value) { - leds |= SLED_HLTH; - } else { - leds &= ~SLED_HLTH; - } - slcdLEDs(slcdHandle); -} - - - -void mlt_heater(int value) -{ - if (value) { - leds |= SLED_MLTH; - } else { - leds &= ~SLED_MLTH; - } - slcdLEDs(slcdHandle); -} - - - -void mlt_pump(int value) -{ - pump_status(value); - if (value) { - leds |= SLED_MLTP; - } else { - leds &= ~SLED_MLTP; - } - slcdLEDs(slcdHandle); -} - - - -int device_out(char *uuid, int value) -{ - devices_list *device; - time_t now, my_timestamp; - int rc, my_value, test_value; - - if (uuid == NULL) - return 0; - - now = time(NULL); - -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - - for (device = Config.devices; device; device = device->next) { - if (! strcmp(uuid, device->uuid)) { - /* - * Execute command if different then the old value. But also - * every 2 minutes because commands can have temporary - * disconnects, or have radio problems. - */ - my_timestamp = device->timestamp; - my_value = device->value; - - if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN)) { - test_value = (value == 0) ? 0 : 1; - } else { - test_value = value; - } - - if ((test_value != my_value) || (((int)now - (int)my_timestamp) >= 120)) { - -#ifdef HAVE_WIRINGPI_H - rc = 0; - if ((device->type == DEVTYPE_GPIO) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) { - - } -#endif - if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) { - if (strncmp(device->address, (char *)"3a", 2) == 0) { - /* - * DS2413. First read state so that we can preserve the state of - * the "other" PIO channel. To make things a bit more complicated - * the bits in the state register differ from the output register. - */ - uint8_t state, output; - - if ((rc = read_w1(device->address, (char *)"state")) >= 0) { - state = (unsigned int)rc; - output = (state & 0x01) + ((state & 0x04) >> 1); - - if (device->subdevice == 0) { - output = (output & 0xfe); - output |= (value == 0) ? 0x01 : 0x00; - } else if (device->subdevice == 1) { - output = (output & 0xfd); - output |= (value == 0) ? 0x02 : 0x00; - } else { - output = 0xff; - } - - if ((write_w1(device->address, (char *)"output", output)) == 0) { - syslog(LOG_NOTICE, "DS2413 PIO%c value=%d (%s)", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1, device->comment); - if (debug) - fprintf(stdout, "DS2413 PIO%c value=%d (%s)\n", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1, device->comment); - device->value = (value == 0) ? 0 : 1; - device->timestamp = time(NULL); - } - } - } - } - -#ifdef USE_SIMULATOR - if ((device->type == DEVTYPE_SIM) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) { - if ((strcmp((char *)"SimHLTheater", device->address) == 0) || - (strcmp((char *)"SimMLTheater", device->address) == 0) || - (strcmp((char *)"SimMLTpump", device->address) == 0)) { - device->value = value; - if (strcmp((char *)"SimHLTheater", device->address) == 0) { - SIM_hlt_value = value; - hlt_heater(value); - } - if (strcmp((char *)"SimMLTheater", device->address) == 0) { - SIM_mlt_value = value; - mlt_heater(value); - } - if (strcmp((char *)"SimMLTpump", device->address) == 0) { - mlt_pump(value); - } - } - } -#endif - } else { -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - return 0; - } - } - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - - return 0; -} - - -/* - * Returns DEVPRESENT_NO if failed. - * Returns DEVPRESENT_YES if success, value contains new value. - */ -int device_in(char *uuid, int *value) -{ - devices_list *device; - int tmp, present; - - if (uuid == NULL) - return 0; - -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - - for (device = Config.devices; device; device = device->next) { - if (! strcmp(uuid, device->uuid)) { - present = device->present; - if (present == DEVPRESENT_YES) { - tmp = device->value + device->offset; - } else { - tmp = 0; - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - *value = tmp; - return present; - } - } - -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - - return DEVPRESENT_NO; -} - - - - -/* - * Auto detect hotplugged or known to be present devices - */ -int devices_detect(void) -{ - struct dirent *de; - DIR *fd; - devices_list *device, *ndev; - int found, subdevices, ival, i, rc = 0; - char buf[40]; - uuid_t uu; -#ifdef HAVE_WIRINGPI_H - int pin; -#endif - - /* - * Scan for 1-wire devices - */ - if ((fd = opendir((char *)"/sys/bus/w1/devices"))) { - while ((de = readdir(fd))) { - if (de->d_name[0] != '.') { - found = FALSE; - for (device = Config.devices; device; device = device->next) { - if (strcmp(device->address,de->d_name) == 0) { - found = TRUE; - break; - } - } - - if (found == FALSE) { - strncpy(buf, de->d_name, 2); - buf[2] = '\0'; - sscanf(buf, "%02x", &ival); - syslog(LOG_NOTICE, "Scan 1-wire %02x %d", ival, ival); - subdevices = 1; - if (strcmp(buf, (char *)"29") == 0) - subdevices = 8; - if (strcmp(buf, (char *)"3a") == 0) - subdevices = 2; - for (i = 0; i < subdevices; i++) { - ndev = (devices_list *)malloc(sizeof(devices_list)); - ndev->next = NULL; - ndev->version = 1; - ndev->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, ndev->uuid); - ndev->type = DEVTYPE_W1; - ndev->direction = DEVDIR_UNDEF; - if (strcmp(buf, (char *)"10") == 0) { - ndev->direction = DEVDIR_IN_ANALOG; - ndev->description = xstrcpy((char *)"DS18S20 Digital thermometer"); - } else if (strcmp(buf, (char *)"22") == 0) { - ndev->direction = DEVDIR_IN_ANALOG; - ndev->description = xstrcpy((char *)"DS1820 Digital thermometer"); - } else if (strcmp(buf, (char *)"28") == 0) { - ndev->direction = DEVDIR_IN_ANALOG; - ndev->description = xstrcpy((char *)"DS18B20 Digital thermometer"); - } else if (strcmp(buf, (char *)"3a") == 0) { - ndev->description = xstrcpy((char *)"DS2413 Dual channel addressable switch"); - ndev->direction = DEVDIR_IN_BIN; - } else if (strcmp(buf, (char *)"3b") == 0) { - ndev->direction = DEVDIR_IN_ANALOG; - ndev->description = xstrcpy((char *)"DS1825 Digital thermometer"); - } else if (strcmp(buf, (char *)"42") == 0) { - ndev->direction = DEVDIR_IN_ANALOG; - ndev->description = xstrcpy((char *)"DS28EA00 Digital thermometer"); - } else if (strcmp(buf, (char *)"w1") == 0) { - ndev->description = xstrcpy((char *)"Master System device"); - } else { - ndev->description = xstrcpy((char *)"Unknown device family "); - ndev->description = xstrcat(ndev->description, buf); - } - ndev->value = ndev->offset = ndev->inuse = 0; - ndev->present = DEVPRESENT_YES; - ndev->address = xstrcpy(de->d_name); - ndev->subdevice = i; - ndev->gpiopin = -1; - ndev->comment = xstrcpy((char *)"Auto detected device"); - ndev->timestamp = time(NULL); - - if (Config.devices == NULL) { - Config.devices = ndev; - } else { - for (device = Config.devices; device; device = device->next) { - if (device->next == NULL) { - device->next = ndev; - break; - } - } - } - rc++; - } - } - } - } - closedir(fd); - } - -#ifdef HAVE_WIRINGPI_H - if (piBoardRev() == 2) { - /* - * Support rev B and newer boards only - */ - found = FALSE; - for (device = Config.devices; device; device = device->next) { - if (device->type == DEVTYPE_GPIO) { - found = TRUE; - break; - } - } - - if (found == FALSE) { - /* - * There were no GPIO devices found. - */ - subdevices = 12; - pin = 0; - for (i = 0; i < subdevices; i++) { - if (i == 8) - pin = 17; - - ndev = (devices_list *)malloc(sizeof(devices_list)); - ndev->next = NULL; - ndev->version = 1; - ndev->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, ndev->uuid); - ndev->type = DEVTYPE_GPIO; - ndev->value = digitalRead(pin); - ndev->offset = 0; - ndev->present = DEVPRESENT_YES; - ndev->address = xstrcpy((char *)"GPIO"); - snprintf(buf, 39, "Raspberry GPIO %d", i); - ndev->description = xstrcpy(buf); - ndev->subdevice = i; - ndev->gpiopin = pin; - ndev->timestamp = time(NULL); - switch (i) { - case 0: - ndev->direction = DEVDIR_OUT_ANALOG; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"MLT heater SSR"); - break; - case 1: - ndev->direction = DEVDIR_OUT_ANALOG; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"MLT heater PWM"); - break; - case 2: - ndev->direction = DEVDIR_OUT_ANALOG; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"MLT pump relay"); - break; - case PANEL_RETURN: - ndev->direction = DEVDIR_IN_BIN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"Frontpanel Return"); - break; - case PANEL_ENTER: - ndev->direction = DEVDIR_IN_BIN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"Frontpanel Enter key"); - break; - case PANEL_DOWN: - ndev->direction = DEVDIR_IN_BIN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"Frontpanel Down key"); - break; - case PANEL_UP: - ndev->direction = DEVDIR_IN_BIN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"Frontpanel Up key"); - break; - case 7: - ndev->direction = DEVDIR_INTERN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"1-Wire bus"); - break; - case 8: - ndev->direction = DEVDIR_OUT_BIN; - ndev->inuse = 1; - ndev->comment = xstrcpy((char *)"Buzzer"); - break; - default: - ndev->direction = DEVDIR_IN_BIN; - ndev->inuse = 0; - ndev->comment = xstrcpy((char *)"Raspberry GPIO"); - } - pin++; - - if (Config.devices == NULL) { - Config.devices = ndev; - } else { - for (device = Config.devices; device; device = device->next) { - if (device->next == NULL) { - device->next = ndev; - break; - } - } - } - rc++; - } - } - } -#endif - -#ifdef USE_SIMULATOR - found = FALSE; - for (device = Config.devices; device; device = device->next) { - if (device->type == DEVTYPE_SIM) { - found = TRUE; - break; - } - } - - if (found == FALSE) { - subdevices = 6; - for (i = 0; i < subdevices; i++) { - ndev = (devices_list *)malloc(sizeof(devices_list)); - ndev->next = NULL; - ndev->version = 1; - ndev->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, ndev->uuid); - ndev->type = DEVTYPE_SIM; - ndev->value = ndev->offset = 0; - ndev->present = DEVPRESENT_YES; - ndev->subdevice = i; - ndev->gpiopin = -1; - ndev->comment = xstrcpy((char *)"Auto detected device"); - ndev->timestamp = time(NULL); - ndev->inuse = 0; - switch (i) { - case 0: ndev->direction = DEVDIR_IN_ANALOG; - ndev->address = xstrcpy((char *)"SimRoomtemp"); - ndev->description = xstrcpy((char *)"Simulated room temperature"); - break; - case 1: ndev->direction = DEVDIR_IN_ANALOG; - ndev->address = xstrcpy((char *)"SimHLTtemp"); - ndev->description = xstrcpy((char *)"Simulated HLT temperature"); - break; - case 2: ndev->direction = DEVDIR_IN_ANALOG; - ndev->address = xstrcpy((char *)"SimMLTtemp"); - ndev->description = xstrcpy((char *)"Simulated MLT temperature"); - break; - case 3: ndev->direction = DEVDIR_OUT_BIN; - ndev->address = xstrcpy((char *)"SimHLTheater"); - ndev->description = xstrcpy((char *)"Simulated HLT heater"); - break; - case 4: ndev->direction = DEVDIR_OUT_BIN; - ndev->address = xstrcpy((char *)"SimMLTheater"); - ndev->description = xstrcpy((char *)"Simulated MLT heater"); - break; - case 5: ndev->direction = DEVDIR_OUT_BIN; - ndev->address = xstrcpy((char *)"SimMLTpump"); - ndev->description = xstrcpy((char *)"Simulated MLT pump"); - break; - } - - if (Config.devices == NULL) { - Config.devices = ndev; - } else { - for (device = Config.devices; device; device = device->next) { - if (device->next == NULL) { - device->next = ndev; - break; - } - } - } - rc++; - } - } -#endif - - return rc; -} - - - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_devices_loop) -#else -void *my_devices_loop(void *threadid) -#endif -{ - devices_list *device; - char *addr = NULL, line[60], *p = NULL; - FILE *fp; - int temp, rc; - - syslog(LOG_NOTICE, "Thread my_devices_loop started"); - if (debug) - fprintf(stdout, "Thread my_devices_loop started\n"); - -#ifdef HAVE_WIRINGPI_H - if ((rc = piHiPri(10))) - syslog(LOG_NOTICE, "my_devices_loop: piHiPri(10) rc=%d", rc); -#endif - - /* - * Loop forever until the external shutdown variable is set. - */ - for (;;) { - - /* - * Process all devices. - */ - for (device = Config.devices; device; device = device->next) { - - if (my_shutdown) - break; - - switch (device->type) { - case DEVTYPE_W1: - /* - * Only tested with DS18B20 but from the kernel source this - * should work with all 1-wire thermometer sensors. - */ - if ((strncmp(device->address, (char *)"10", 2) == 0) || - (strncmp(device->address, (char *)"22", 2) == 0) || - (strncmp(device->address, (char *)"28", 2) == 0) || - (strncmp(device->address, (char *)"3b", 2) == 0) || - (strncmp(device->address, (char *)"42", 2) == 0)) { - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, device->address); - addr = xstrcat(addr, (char *)"/w1_slave"); - if ((fp = fopen(addr, "r"))) { - if (device->present != DEVPRESENT_YES) { - syslog(LOG_NOTICE, "sensor %s is back", device->address); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - device->present = DEVPRESENT_YES; -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - /* - * The output looks like: - * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES - * 72 01 4b 46 7f ff 0e 10 57 t=23125 - */ - fgets(line, 50, fp); - line[strlen(line)-1] = '\0'; - if ((line[36] == 'Y') && (line[37] == 'E')) { - /* CRC is Ok, continue */ - fgets(line, 50, fp); - line[strlen(line)-1] = '\0'; - strtok(line, (char *)"="); - p = strtok(NULL, (char *)"="); - rc = sscanf(p, "%d", &temp); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - if ((rc == 1) && (device->value != temp)) { - device->value = temp; - device->timestamp = time(NULL); - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } else { - syslog(LOG_NOTICE, "sensor %s CRC error", device->address); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - device->present = DEVPRESENT_ERROR; -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - fclose(fp); - } else { - if (device->present != DEVPRESENT_NO) { - syslog(LOG_NOTICE, "sensor %s is missing", device->address); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - device->present = DEVPRESENT_NO; -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - } - free(addr); - addr = NULL; - } /* if temperature sensor */ - /* - * DS2413 Dual channel addressable switch - */ - if (strncmp(device->address, (char *)"3a", 2) == 0) { - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, device->address); - addr = xstrcat(addr, (char *)"/state"); - - if ((access(addr, R_OK)) == 0) { - if (device->present != DEVPRESENT_YES) { - syslog(LOG_NOTICE, "DS2413 %s is back", device->address); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - device->present = DEVPRESENT_YES; -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - /* - * First make sure that if this device is configured as input - * to drive the output high. - */ - if (device->direction == DEVDIR_IN_BIN) { - uint8_t state, output; - - if ((rc = read_w1(device->address, (char *)"state")) >= 0) { - state = (unsigned int)rc; - output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2); /* Both latch states */ - if (device->subdevice == 0) { - output = (output & 0xfe); - output |= 0x01; - } else if (device->subdevice == 1) { - output = (output & 0xfd); - output |= 0x02; - } else { - output = 0xff; - } - write_w1(device->address, (char *)"output", output); - } - } - if ((rc = read_w1(device->address, (char *)"state")) >= 0) { -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - /* - * Read PIOA or PIOB pin state bits - */ - if (device->subdevice == 0) - device->value = (rc & 0x01) ? 0 : 1; - else if (device->subdevice == 1) - device->value = (rc & 0x04) ? 0 : 1; - device->timestamp = time(NULL); -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - } else { - if (device->present != DEVPRESENT_NO) { - syslog(LOG_NOTICE, "DS2413 %s is missing", device->address); -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - device->present = DEVPRESENT_NO; -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - } - } - free(addr); - addr = NULL; - } - - break; - -#ifdef HAVE_WIRINGPI_H - case DEVTYPE_GPIO: - if (device->direction == DEVDIR_IN_BIN) { - piLock(LOCK_DEVICES); - device->value = digitalRead(device->gpiopin); - device->offset = 0; - device->timestamp = time(NULL); - piUnlock(LOCK_DEVICES); - } - break; - -#endif -#ifdef USE_SIMULATOR - case DEVTYPE_SIM: -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - if (Config.simulator) { - if (device->subdevice == 0) { - device->value = (int)(Config.simulator->room_temperature * 1000); - device->timestamp = time(NULL); - } else if (device->subdevice == 1) { - device->value = (int)(Config.simulator->hlt_temperature * 1000); - device->timestamp = time(NULL); - } else if (device->subdevice == 2) { - device->value = (int)(Config.simulator->mlt_temperature * 1000); - device->timestamp = time(NULL); - } - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - break; -#endif - default: - break; - } - - /* - * Delay a bit after procesing a device. - */ - usleep(10000); - } - - if (my_shutdown) - break; - /* - * Delay a bit after all devices - */ - usleep(100000); - } - - syslog(LOG_NOTICE, "Thread my_devices_loop stopped"); - if (debug) - fprintf(stdout, "Thread my_devices_loop stopped\n"); - return 0; -} - - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/devices.h --- a/brewco/devices.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#ifndef MY_DEVICES_H -#define MY_DEVICES_H - - -int device_out(char *, int); -int device_in(char *, int *); -int devices_detect(void); - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_devices_loop); -#else -void *my_devices_loop(void *); -#endif - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/keyboard.c --- a/brewco/keyboard.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +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 "lcd-pcf8574.h" -#include "slcd.h" -#include "keyboard.h" - - - -/* - * 10 Milliseconds counts for a key to be short or long pressed. - */ -#define PRESS_NORMAL 5 -#define PRESS_LONG 200 - - - -extern int my_shutdown; -extern int debug; -extern int setupmenu; -extern uint16_t keys; -extern uint16_t leds; -extern int slcdHandle; - -int Key_Enter = FALSE; -int Key_Return = FALSE; -int Key_Up = FALSE; -int Key_Down = FALSE; - -int previous_key = KEY_NONE; - - -int keypressed(void); - - - -/* - * Wait for a key. Return the pressed key. - */ -int keywait(void) -{ - int key; - - do { - usleep(50000); - slcdDummy(slcdHandle); - key = keycheck(); - if (my_shutdown) - return KEY_NONE; - } while (key == KEY_NONE); - - fprintf(stdout, "keywait %d\n", key); - return key; -} - - - -/* - * Check for a key. Return last pressed key or none. - */ -int keycheck(void) -{ - int key, retkey = KEY_NONE; - - key = keypressed(); - if ((key == KEY_NONE) && (previous_key != KEY_NONE)) { - retkey = previous_key; - } - - previous_key = key; - return retkey; -} - - - -int keypressed(void) -{ - if (Key_Enter && Key_Up && Key_Down && Key_Return) - return KEY_ALL; - if (Key_Up && Key_Down) - return KEY_ESCAPE; - if (Key_Up) - return KEY_UP; - if (Key_Down) - return KEY_DOWN; - if (Key_Enter) - return KEY_ENTER; - if (Key_Return) - return KEY_RETURN; - return KEY_NONE; -} - - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_keyboard_loop) -#else -void *my_keyboard_loop(void *threadid) -#endif -{ - int Return = 0, Enter = 0, Up = 0, Down = 0; - time_t Last = (time_t)0, Now; - -#ifdef HAVE_WIRINGPI_H - pinMode(PANEL_RETURN, INPUT); - pinMode(PANEL_ENTER, INPUT); - pinMode(PANEL_UP, INPUT); - pinMode(PANEL_DOWN, INPUT); -#endif - - syslog(LOG_NOTICE, "Thread my_keyboard_loop started"); - if (debug) - fprintf(stdout, "Thread my_keyboard_loop started\n"); - - /* - * Loop forever until the external shutdown variable is set. - */ - for (;;) { - if (my_shutdown) - break; - -#ifdef HAVE_WIRINGPI_H - if (digitalRead(PANEL_ENTER) && ((keys & 0x0001) == 0)) { -#else - if ((keys & 0x0001) == 0) { -#endif - Enter = 0; - Key_Enter = FALSE; - } else { - Enter++; - if (Enter > PRESS_NORMAL) - Key_Enter = TRUE; - } - -#ifdef HAVE_WIRINGPI_H - if (digitalRead(PANEL_RETURN) && ((keys & 0x0002) == 0)) { -#else - if ((keys & 0x0002) == 0) { -#endif - Return = 0; - Key_Return = FALSE; - } else { - Return++; - if (Return > PRESS_NORMAL) - Key_Return = TRUE; - } - -#ifdef HAVE_WIRINGPI_H - if (digitalRead(PANEL_UP) && ((keys & 0x0008) == 0)) { -#else - if ((keys & 0x0008) == 0) { -#endif - Up = 0; - Key_Up = FALSE; - } else { - Up++; - if (Up > PRESS_NORMAL) - Key_Up = TRUE; - } - -#ifdef HAVE_WIRINGPI_H - if (digitalRead(PANEL_DOWN) && ((keys & 0x0004) == 0)) { -#else - if ((keys & 0x0004) == 0) { -#endif - Down = 0; - Key_Down = FALSE; - } else { - Down++; - if (Down > PRESS_NORMAL) - Key_Down = TRUE; - } - - Now = time(NULL); - if (Now != Last) { - Last = Now; - } - - /* - * Loop 10 milliseconds - */ - usleep(10000); - } - - syslog(LOG_NOTICE, "Thread my_keyboard_loop stopped"); - if (debug) - fprintf(stdout, "Thread my_keyboard_loop stopped\n"); - return 0; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/keyboard.h --- a/brewco/keyboard.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#ifndef _KEYBOARD_H -#define _KEYBOARD_H - - - -/* - * GPIO pins for the push buttons. - */ -#define PANEL_RETURN 3 -#define PANEL_ENTER 4 -#define PANEL_DOWN 5 -#define PANEL_UP 6 - - -/* - * Key names - */ -#define KEY_NONE 0 -#define KEY_UP 1 -#define KEY_DOWN 2 -#define KEY_RETURN 3 -#define KEY_ENTER 4 -#define KEY_ESCAPE 12 -#define KEY_ALL 99 - - -int keywait(void); -int keycheck(void); - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_keyboard_loop); -#else -void *my_keyboard_loop(void *); -#endif - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/lcd-pcf8574.c --- a/brewco/lcd-pcf8574.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * lcd-pcf8574.c: - * Text-based LCD driver library code - * This is designed to drive the HD44780U LCD display connected via - * a "LCM1602 IIC A0 A1 A2" board with a PCF8574 I2C controller. - * - * Copyright (c) 2012-2013 Gordon Henderson. - * Copyright (c) 2014 Michiel Broek. - *********************************************************************** - * - * mbsePi is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * mbsePi 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with wiringPi. If not, see . - *********************************************************************** - */ - -#include "brewco.h" -#include "lcd-pcf8574.h" -#include "slcd.h" - - -int lcdHandle; -int slcdHandle; - - -#ifdef HAVE_WIRINGPI_H -struct lcdDataStruct -{ - int bits, rows, cols ; - int rsPin, strbPin ; - int dataPins [8] ; - int cx, cy ; -}; - -extern struct lcdDataStruct *lcds [MAX_LCDS]; -#endif -extern sys_config Config; -extern uint16_t leds; - - -/* - * setBacklight: - ********************************************************************************* - */ -void setBacklight(int value) -{ -#ifdef HAVE_WIRINGPI_H - pinMode (AF_BACKLIGHT, OUTPUT) ; - digitalWrite (AF_BACKLIGHT, (value & 1)) ; -#endif - if (value) { - leds |= SLED_LCD; - } else { - leds &= ~SLED_LCD; - } - slcdLEDs(slcdHandle); -} - - -/* - * initLCD: - ********************************************************************************* - */ - -int initLCD(int cols, int rows) -{ - if (!((rows == 1) || (rows == 2) || (rows == 4))) { - fprintf (stderr, "rows must be 1, 2 or 4\n") ; - return EXIT_FAILURE ; - } - - if (!((cols == 16) || (cols == 20))) { - fprintf (stderr, "cols must be 16 or 20\n") ; - return EXIT_FAILURE ; - } - -#ifdef HAVE_WIRINGPI_H - pcf8574Setup(AF_BASE, 0x27) ; - pinMode (AF_RW, OUTPUT) ; - digitalWrite (AF_RW, LOW) ; // Not used with wiringPi - always in write mode - - /* - * The other control pins are initialised with lcdInit () - */ - lcdHandle = lcdInit (rows, cols, 4, AF_RS, AF_E, AF_DB4, AF_DB5, AF_DB6, AF_DB7, 0, 0, 0, 0) ; - if (lcdHandle < 0) { - fprintf (stderr, "lcdInit failed\n") ; - return -1 ; - } - - lcdClear (lcdHandle) ; -#endif - - slcdHandle = slcdInit(0, rows, cols); - if (slcdHandle < 0) { - fprintf (stderr, "slcdInit failed\n") ; - return -1; - } - slcdClear(slcdHandle); - setBacklight(1); - - return 0 ; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/lcd-pcf8574.h --- a/brewco/lcd-pcf8574.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -#ifndef LCD_PCF8574_H -#define LCD_PCF8574_H - - -#ifdef HAVE_WIRINGPI_H - -// Defines for the pcf8574 Pi LCD interface board -#define AF_BASE 100 - -#define AF_RS (AF_BASE + 0) -#define AF_RW (AF_BASE + 1) -#define AF_E (AF_BASE + 2) -#define AF_BACKLIGHT (AF_BASE + 3) -#define AF_DB4 (AF_BASE + 4) -#define AF_DB5 (AF_BASE + 5) -#define AF_DB6 (AF_BASE + 6) -#define AF_DB7 (AF_BASE + 7) - -#endif - -void setBacklight (int); -int initLCD (int, int); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/lock.c --- a/brewco/lock.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +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 "lock.h" -#include "brewco.h" - -extern char *varpath; - - -/* - * Put a lock on this program. - */ -int lockprog(char *name) -{ - char *tempfile, *lockfile; - FILE *fp; - pid_t oldpid; - - tempfile = calloc(PATH_MAX, sizeof(char)); - lockfile = calloc(PATH_MAX, sizeof(char)); - - snprintf(tempfile, PATH_MAX, "%s%s.tmp", varpath, name); - snprintf(lockfile, PATH_MAX, "%s%s.pid", varpath, name); - - if ((fp = fopen(tempfile, "w")) == NULL) { - perror(name); - printf("Can't create lockfile \"%s\"\n", tempfile); - free(tempfile); - free(lockfile); - return 1; - } - fprintf(fp, "%10u\n", getpid()); - fclose(fp); - - while (TRUE) { - if (link(tempfile, lockfile) == 0) { - unlink(tempfile); - free(tempfile); - free(lockfile); - return 0; - } - if ((fp = fopen(lockfile, "r")) == NULL) { - perror(name); - printf("Can't open lockfile \"%s\"\n", tempfile); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - if (fscanf(fp, "%u", &oldpid) != 1) { - perror(name); - printf("Can't read old pid from \"%s\"\n", tempfile); - fclose(fp); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - fclose(fp); - if (kill(oldpid,0) == -1) { - if (errno == ESRCH) { - printf("Stale lock found for pid %u\n", oldpid); - unlink(lockfile); - /* no return, try lock again */ - } else { - perror(name); - printf("Kill for %u failed\n",oldpid); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - } else { - printf("Another %s is already running, pid=%u\n", name, oldpid); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - } -} - - - -void ulockprog(char *name) -{ - char *lockfile; - pid_t oldpid; - FILE *fp; - - lockfile = calloc(PATH_MAX, sizeof(char)); - snprintf(lockfile, PATH_MAX, "%s%s.pid", varpath, name); - - if ((fp = fopen(lockfile, "r")) == NULL) { - syslog(LOG_NOTICE, "Can't open lockfile \"%s\"", lockfile); - free(lockfile); - return; - } - - if (fscanf(fp, "%u", &oldpid) != 1) { - syslog(LOG_NOTICE, "Can't read old pid from \"%s\"", lockfile); - fclose(fp); - unlink(lockfile); - free(lockfile); - return; - } - - fclose(fp); - - if (oldpid == getpid()) { - (void)unlink(lockfile); - } - - free(lockfile); -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/lock.h --- a/brewco/lock.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef LOCK_H -#define LOCK_H - - -int lockprog(char *); -void ulockprog(char *); - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/logger.c --- a/brewco/logger.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014-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 "logger.h" -#include "brewco.h" -#include "util.h" -#include "xutil.h" - -extern char *varpath; - - -void initlog(char *name) -{ - char buf[128]; - - snprintf(buf, 127, "Fase,hltInput,hltOutput,hltSetpoint,mltInput,mltOutput,mltSetpoint"); - logger(name, buf); -} - - - -void logger(char *name, char *data) -{ - struct timeval now; - struct tm ptm; - char *outstr = NULL, *logfile = NULL; - FILE *fp; - - logfile = xstrcpy(varpath); - logfile = xstrcat(logfile, (char *)"log/brew-"); - logfile = xstrcat(logfile, name); - mkdirs(logfile, 0755); - logfile = xstrcat(logfile, (char *)".log"); - - gettimeofday(&now, NULL); - localtime_r(&now.tv_sec, &ptm); - outstr = calloc(10240, sizeof(char)); - snprintf(outstr, 10239, "%04d-%02d-%02d %02d:%02d,%s\n", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, data); - - if ((fp = fopen(logfile, "a+"))) { - fprintf(fp, outstr); - fclose(fp); - } else { - syslog(LOG_NOTICE, "logger: cannot open %s for writing", logfile); - } - - free(outstr); - outstr = NULL; - free(logfile); - logfile = NULL; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/logger.h --- a/brewco/logger.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#ifndef LOGGER_H -#define LOGGER_H - - -void logger(char *, char *); -void initlog(char *); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/pid.c --- a/brewco/pid.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +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. - * - * Based on the Arduino PID Library 1.1.1 by Brett Beauregard - * This Library is licensed under a GPLv3 License - *****************************************************************************/ - -#include "brewco.h" -#include "pid.h" -#include "util.h" - - -/* - * The parameters specified here are those for for which we can't set up - * reliable defaults, so we need to have the user set them. - */ -void PID_init(pid_var *pid, double *Input, double *Output, double *Setpoint, double Kp, double Ki, double Kd, int ControllerDirection) -{ - pid->myOutput = Output; - pid->myInput = Input; - pid->mySetpoint = Setpoint; - pid->inAuto = FALSE; - PID_setOutputLimits(pid, 0, 255); - pid->SampleTime = 100; - PID_setDirection(pid, ControllerDirection); - PID_setTunings(pid, Kp, Ki, Kd); - pid->lastTime = millis() - pid->SampleTime; -} - - - -/* - * Allows the controller Mode to be set to manual (0) or Automatic (non-zero) - * when the transition from manual to auto occurs, the controller is - * automatically initialized - */ -void PID_setMode(pid_var *pid, int Mode) -{ - int newAuto = (Mode == P_AUTOMATIC); - - if (newAuto != pid->inAuto) { - /* - * we just went from manual to auto - */ - pid->ITerm = *pid->myOutput; - pid->lastInput = *pid->myInput; - if (pid->ITerm > pid->outMax) - pid->ITerm = pid->outMax; - else if (pid->ITerm < pid->outMin) - pid->ITerm = pid->outMin; - /* - * If turned to manual, turn output off. - */ - if (Mode == P_MANUAL) - *pid->myOutput = pid->outMin; - } - pid->inAuto = newAuto; -} - - - -/* - * This function will be used far more often than SetInputLimits. while - * the input to the controller will generally be in the 0-1023 range (which is - * the default already,) the output will be a little different. maybe they'll - * be doing a time window and will need 0-8000 or something. or maybe they'll - * want to clamp it from 0-125. who knows. at any rate, that can all be done - * here. - */ -void PID_setOutputLimits(pid_var *pid, double Min, double Max) -{ - if (Min >= Max) - return; - - pid->outMin = Min; - pid->outMax = Max; - - if (pid->inAuto == P_AUTOMATIC) { - if (*pid->myOutput > pid->outMax) - *pid->myOutput = pid->outMax; - else if (*pid->myOutput < pid->outMin) - *pid->myOutput = pid->outMin; - - if (pid->ITerm > pid->outMax) - pid->ITerm = pid->outMax; - else if (pid->ITerm < pid->outMin) - pid->ITerm = pid->outMin; - } -} - - - -/* - * This function allows the controller's dynamic performance to be adjusted. - * it's called automatically from the constructor, but tunings can also - * be adjusted on the fly during normal operation. - */ -void PID_setTunings(pid_var *pid, double Kp, double Ki, double Kd) -{ - if (Kp < 0 || Ki < 0 || Kd < 0) - return; - pid->dispKp = Kp; - pid->dispKi = Ki; - pid->dispKd = Kd; - - double SampleTimeInSec = ((double)pid->SampleTime) / 1000; - pid->Kp = Kp; - pid->Ki = Ki * SampleTimeInSec; - pid->Kd = Kd / SampleTimeInSec; - - if (pid->Direction == P_REVERSE) { - pid->Kp = (0 - pid->Kp); - pid->Ki = (0 - pid->Ki); - pid->Kd = (0 - pid->Kd); - } -} - - - -/* - * The PID will either be connected to a DIRECT acting process (+Output leads - * to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to - * know which one, because otherwise we may increase the output when we should - * be decreasing. This is called from PID_init(). - */ -void PID_setDirection(pid_var *pid, int Direction) -{ - if (pid->inAuto && Direction != pid->Direction) { - pid->Kp = (0 - pid->Kp); - pid->Ki = (0 - pid->Ki); - pid->Kd = (0 - pid->Kd); - } - pid->Direction = Direction; -} - - - -/* - * sets the period, in Milliseconds, at which the calculation is performed. - */ -void PID_setSampleTime(pid_var *pid, int NewSampleTime) -{ - if (NewSampleTime > 0) { - double ratio = (double)NewSampleTime / (double)pid->SampleTime; - - pid->Ki *= ratio; - pid->Kd /= ratio; - pid->SampleTime = NewSampleTime; - } -} - - - -/* - * Just because you set the Kp=-1 doesn't mean it actually happened. these - * functions query the internal state of the PID. they're here for display - * purposes. this are the functions the PID Front-end uses for example - */ -double PID_getKp(pid_var *pid) -{ - return pid->dispKp; -} - - - -double PID_getKi(pid_var *pid) -{ - return pid->dispKi; -} - - - -double PID_getKd(pid_var *pid) -{ - return pid->dispKd; -} - - - -int PID_getMode(pid_var *pid) -{ - return pid->inAuto ? P_AUTOMATIC : P_MANUAL; -} - - - -int PID_getDirection(pid_var *pid) -{ - return pid->Direction; -} - - - -int PID_getSampleTime(pid_var *pid) -{ - return pid->SampleTime; -} - - - -/* - * This, as they say, is where the magic happens. this function should be called - * every time "void loop()" executes. the function will decide for itself whether a new - * pid Output needs to be computed. returns true when the output is computed, - * false when nothing has been done. - */ -int PID_compute(pid_var *pid) -{ - if (! pid->inAuto) - return FALSE; - - long now = millis(); - long timeChange = (now - pid->lastTime); - - if (timeChange >= pid->SampleTime) { - /* - * Compute all the working error variables - */ - double input = *pid->myInput; - double error = *pid->mySetpoint - input; - pid->ITerm += (pid->Ki * error); - if (pid->ITerm > pid->outMax) - pid->ITerm = pid->outMax; - else if (pid->ITerm < pid->outMin) - pid->ITerm = pid->outMin; - double dInput = input - pid->lastInput; - - /* - * Compute PID output - */ - double output = pid->Kp * error + pid->ITerm - pid->Kd * dInput; - if (output > pid->outMax) - output = pid->outMax; - else if (output < pid->outMin) - output = pid->outMin; - *pid->myOutput = output; - - /* - * Remember some variables for the next time - */ - pid->lastInput = input; - pid->lastTime = now; - return TRUE; - } - - return FALSE; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/pid.h --- a/brewco/pid.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -#ifndef PID_H -#define PID_H - - -#define P_MANUAL 0 -#define P_AUTOMATIC 1 -#define P_DIRECT 0 -#define P_REVERSE 1 - -typedef struct _pid_var { - double Kp; /* (P)roportional Tuning Parameter */ - double Ki; /* (I)ntegral Tuning Parameter */ - double Kd; /* (D)erivative Tuning Parameter */ - double dispKp; - double dispKi; - double dispKd; - int Direction; /* Controller direction */ - double *myInput; /* Input parameter */ - double *myOutput; /* Output parameter */ - double *mySetpoint; /* Setpoint parameter */ - long lastTime; /* Last compute time */ - double ITerm; - double lastInput; - long SampleTime; - double outMin; - double outMax; - int inAuto; -} pid_var; - - -void PID_init(pid_var *, double *, double *, double *, double, double, double, int); -void PID_setMode(pid_var *, int); -void PID_setOutputLimits(pid_var *, double, double); -void PID_setTunings(pid_var *, double, double, double); -void PID_setDirection(pid_var *, int); -void PID_setSampleTime(pid_var *, int); -double PID_getKp(pid_var *); -double PID_getKi(pid_var *); -double PID_getKd(pid_var *); -int PID_getMode(pid_var *); -int PID_getDirection(pid_var *); -int PID_getSampleTime(pid_var *); -int PID_compute(pid_var *); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/prompt.c --- a/brewco/prompt.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +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 "slcd.h" -#include "prompt.h" - - -extern int debug; -extern sys_config Config; -extern int lcdHandle; -extern int slcdHandle; - - - -void prompt(int idx, char *text) -{ - char message[81]; - int line; - - switch (idx) { - case 0: -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdClear(lcdHandle); -#endif - slcdClear(slcdHandle); -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_LCD); -#endif - return; - case 100: if (text == NULL) - snprintf(message, Config.lcd_cols + 1, " "); - else - snprintf(message, Config.lcd_cols + 1, text); - break; - case 101: snprintf(message, Config.lcd_cols + 1, " Brewco %s \007", VERSION); - break; - case 102: snprintf(message, Config.lcd_cols + 1, " SETUP MENU "); - break; - case 103: snprintf(message, Config.lcd_cols + 1, " AUTOMATIC MODE "); - break; - case 104: snprintf(message, Config.lcd_cols + 1, " MANUAL MODE "); - break; - case 111: snprintf(message, Config.lcd_cols + 1, "AUTO --> Prepare "); - break; - case 112: snprintf(message, Config.lcd_cols + 1, "AUTO --> Phytase "); - break; - case 113: snprintf(message, Config.lcd_cols + 1, "AUTO --> Glucanase "); - break; - case 114: snprintf(message, Config.lcd_cols + 1, "AUTO --> Protease "); - break; - case 115: snprintf(message, Config.lcd_cols + 1, "AUTO --> \342-Amylase "); /* Beta */ - break; - case 116: snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 1"); /* Alpha */ - break; - case 117: snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 2"); - break; - case 118: snprintf(message, Config.lcd_cols + 1, "AUTO --> Mash Out "); - break; - case 119: snprintf(message, Config.lcd_cols + 1, "AUTO --> Boil "); - break; - case 120: snprintf(message, Config.lcd_cols + 1, "AUTO --> Cooling "); - break; - case 121: snprintf(message, Config.lcd_cols + 1, "AUTO --> Whirlpool "); - break; - case 122: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hopstand 1 "); - break; - case 123: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hopstand 2 "); - break; - case 124: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hopstand 3 "); - break; - case 125: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hop xx "); - break; - - case 131: snprintf(message, Config.lcd_cols + 1, " Change Name "); - break; - case 132: snprintf(message, Config.lcd_cols + 1, " Toggle Yes/No "); - break; - case 133: snprintf(message, Config.lcd_cols + 1, " Change temperature "); - break; - case 134: snprintf(message, Config.lcd_cols + 1, " Change time "); - break; - case 137: snprintf(message, Config.lcd_cols + 1, " Direct/Reverse "); - break; - case 138: snprintf(message, Config.lcd_cols + 1, " Change parameter "); - break; - - case 191: snprintf(message, Config.lcd_cols + 1, " Edit recipe "); - break; - case 192: snprintf(message, Config.lcd_cols + 1, " Edit PID "); - 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: if (text == NULL) - snprintf(message, Config.lcd_cols + 1, " "); - else - snprintf(message, Config.lcd_cols + 1, text); - break; - case 202: snprintf(message, Config.lcd_cols + 1, " Manage Recipes "); - break; - case 203: snprintf(message, Config.lcd_cols + 1, " Manage Brewsystems "); - break; - case 204: snprintf(message, Config.lcd_cols + 1, " Manage Devices "); - break; - case 205: snprintf(message, Config.lcd_cols + 1, " Manage Simulators "); - break; - case 206: snprintf(message, Config.lcd_cols + 1, " Set Automation "); - break; - case 207: snprintf(message, Config.lcd_cols + 1, " Delay start? "); - break; - case 208: snprintf(message, Config.lcd_cols + 1, " Resume Process "); - break; - case 209: snprintf(message, Config.lcd_cols + 1, " Water Added? "); - break; - case 210: snprintf(message, Config.lcd_cols + 1, " Pump Prime "); - break; - case 211: snprintf(message, Config.lcd_cols + 1, " Setting Delay "); - break; - case 212: snprintf(message, Config.lcd_cols + 1, " To be started in "); - break; - case 213: snprintf(message, Config.lcd_cols + 1, " Iodine test "); - break; - case 214: snprintf(message, Config.lcd_cols + 1, " START COOLING "); - break; - case 215: snprintf(message, Config.lcd_cols + 1, " WHIRLPOOL "); - break; - case 216: snprintf(message, Config.lcd_cols + 1, " Timing Whirlpool "); - break; - case 217: snprintf(message, Config.lcd_cols + 1, " Brewing Process "); - break; - case 218: snprintf(message, Config.lcd_cols + 1, " Add Brewsystem? "); - break; - case 219: snprintf(message, Config.lcd_cols + 1, " Mash added? "); - break; - case 220: snprintf(message, Config.lcd_cols + 1, " Mash Removed? "); - break; - case 221: snprintf(message, Config.lcd_cols + 1, " Select Recipe "); - break; - case 222: snprintf(message, Config.lcd_cols + 1, " Select Brewsystem "); - break; - case 223: snprintf(message, Config.lcd_cols + 1, " Select Device "); - break; - case 300: if (text == NULL) - snprintf(message, Config.lcd_cols + 1, " "); - else - snprintf(message, Config.lcd_cols + 1, text); - break; - case 301: snprintf(message, Config.lcd_cols + 1, " Finished "); - break; - case 302: snprintf(message, Config.lcd_cols + 1, " Shutting down "); - break; - case 303: snprintf(message, Config.lcd_cols + 1, " Manual HLT "); - break; - case 304: snprintf(message, Config.lcd_cols + 1, " Manual MLT "); - break; - case 400: if (text == NULL) - snprintf(message, Config.lcd_cols + 1, " "); - else - snprintf(message, Config.lcd_cols + 1, text); - break; - case 401: snprintf(message, Config.lcd_cols + 1, "--- MAN AUTO SETUP"); - break; - case 402: snprintf(message, Config.lcd_cols + 1, "--- dwn quit ok "); - break; - case 403: snprintf(message, Config.lcd_cols + 1, " up dwn quit ok "); - break; - case 404: snprintf(message, Config.lcd_cols + 1, " up --- quit ok "); - break; - case 405: snprintf(message, Config.lcd_cols + 1, "--- --- quit ok "); - break; - case 406: snprintf(message, Config.lcd_cols + 1, "UP* *DWN heat pmp "); - break; - case 407: snprintf(message, Config.lcd_cols + 1, "--- --- No Yes "); - break; - case 408: snprintf(message, Config.lcd_cols + 1, "--- --- Ok --- "); - break; - case 409: snprintf(message, Config.lcd_cols + 1, "UP* *DWN Pause --- "); - break; - case 410: snprintf(message, Config.lcd_cols + 1, " Continue: Yes No "); - break; - case 411: snprintf(message, Config.lcd_cols + 1, "UP* *DWN --- pmp "); - break; - case 412: snprintf(message, Config.lcd_cols + 1, "Up Dwn Exit Ok "); - break; - case 413: snprintf(message, Config.lcd_cols + 1, "UP* *DWN heat --- "); - break; - case 414: snprintf(message, Config.lcd_cols + 1, "add dwn quit ok "); - break; - case 415: snprintf(message, Config.lcd_cols + 1, "add --- quit ok "); - break; - case 416: snprintf(message, Config.lcd_cols + 1, "add --- quit --- "); - break; - case 417: snprintf(message, Config.lcd_cols + 1, " up dwn next ok "); - break; - case 418: snprintf(message, Config.lcd_cols + 1, "--- --- Pause --- "); - break; - case 419: snprintf(message, Config.lcd_cols + 1, "--* *-- --- pmp "); - break; - - // 12345678901234567890 - default: snprintf(message, Config.lcd_cols + 1, " N/A N/A"); - } - - if (idx < 200) - line = 0; - else if (idx < 300) - line = 1; - else if (idx < 400) - line = 2; - else - line = 3; - - fprintf(stdout, "%d %d '%s'\n", line, Config.lcd_cols, message); - -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 0, line); - lcdPuts(lcdHandle, message); - -#endif - slcdPosition(slcdHandle, 0, line); - slcdPuts(slcdHandle, message); -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_LCD); -#endif -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/prompt.h --- a/brewco/prompt.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -#ifndef _PROMPT_H -#define _PROMPT_H - -void prompt(int, char *); - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdconfig.c --- a/brewco/rdconfig.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1411 +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 "rdconfig.h" -#include "brewco.h" -#include "util.h" -#include "xutil.h" - -int debug = TRUE; -sys_config Config; /* System configuration */ -extern char *etcpath; - - -#define MY_ENCODING "utf-8" - -const char TEMPSTATE[3][8] = { "OK", "MISSING", "ERROR" }; -const char DEVTYPE[6][5] = { "NA", "W1", "GPIO", "I2C", "SPI", "SIM" }; -const char DEVPRESENT[4][6] = { "UNDEF", "NO", "YES", "ERROR" }; -const char DEVDIR[7][11] = { "UNDEF", "IN_BIN", "OUT_BIN", "IN_ANALOG", "OUT_ANALOG", "OUT_PWM", "INTERN" }; -const char WHIRLPOOL_TYPE[3][5] = { "OFF", "COLD", "HOT" }; -const char PIDDIRECTION[2][8] = { "DIRECT", "REVERSE" }; -const char PIDMODE[2][10] = { "MANUAL", "AUTOMATIC" }; - - -void killconfig(void) -{ - units_list *unit; - devices_list *device; - - if (Config.name) - free(Config.name); - Config.name = NULL; - - Config.my_port = 6554; - Config.tempFormat = 'C'; - if (Config.roomtemp) - free(Config.roomtemp); - Config.roomtemp = NULL; - Config.lcd_cols = 20; - Config.lcd_rows = 4; - - for (unit = Config.units; unit; unit = unit->next) { - if (unit->uuid) - free(unit->uuid); - if (unit->name) - free(unit->name); - if (unit->hlt_sensor.uuid) - free(unit->hlt_sensor.uuid); - if (unit->mlt_sensor.uuid) - free(unit->mlt_sensor.uuid); - if (unit->hlt_heater.uuid) - free(unit->hlt_heater.uuid); - if (unit->mlt_heater.uuid) - free(unit->mlt_heater.uuid); - if (unit->mlt_pump.uuid) - free(unit->mlt_pump.uuid); - if (unit->PID_hlt) - free(unit->PID_hlt); - if (unit->PID_mlt) - free(unit->PID_mlt); - free(unit); - } - Config.units = NULL; - - for (device = Config.devices; device; device = device->next) { - if (device->uuid) - free(device->uuid); - if (device->address) - free(device->address); - if (device->description) - free(device->description); - if (device->comment) - free(device->comment); - free(device); - } - Config.devices = NULL; - -#ifdef USE_SIMULATOR - if (Config.simulator) - free(Config.simulator); - Config.simulator = NULL; -#endif -} - - - -int do_wrconfig(void); -int do_wrconfig(void) -{ - int rc = 0; - FILE *fp; - char *mypath = NULL; - xmlTextWriterPtr writer; - xmlBufferPtr buf; - units_list *unit; - devices_list *device; - - /* - * Create a new XML buffer, to which the XML document will be written - */ - if ((buf = xmlBufferCreate()) == NULL) { - syslog(LOG_NOTICE, "wrconfig: error creating the xml buffer"); - return 1; - } - - /* - * Create a new XmlWriter for memory, with no compression. - */ - if ((writer = xmlNewTextWriterMemory(buf, 0)) == NULL) { - syslog(LOG_NOTICE, "wrconfig: error creating the xml writer"); - return 1; - } - - /* - * Use indentation instead of one long line - */ - if ((rc = xmlTextWriterSetIndent(writer, 2)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error setting Indent"); - return 1; - } - - /* - * Start the document with the xml default for the version, - * encoding ISO 8859-1 and the default for the standalone - * declaration. - */ - if ((rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartDocument"); - return 1; - } - - /* - * Start an element named "BREWCO". Since thist is the first - * element, this will be the root element of the document. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWCO")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - - /* - * Add an attribute with name "VERSION" and value "1" to BRWCO. - */ - if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", Config.name)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LISTEN_PORT", "%d", Config.my_port)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMPFORMAT", "%c", Config.tempFormat)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (Config.roomtemp) { - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_UUID", "%s", Config.roomtemp->uuid)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_STATE", "%d", Config.roomtemp->state)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_VALUE", "%d", Config.roomtemp->value)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - } - - /* - * Start an element named "LCDS" as child of BREWCO. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCDS")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - /* - * Start one LCD. It is possible to connect 7 LCD displays on the i2c bus. - * However this program doesn't use more then one yet. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCD")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "0x%x", Config.lcd_address)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLUMNS", "%d", Config.lcd_cols)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROWS", "%d", Config.lcd_rows)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - /* - * Close the element named LCD. - */ - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - /* - * Close the element LCDS. - */ - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * Brewsystems - */ - if (Config.units) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWSYSTEMS")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - for (unit = Config.units; unit; unit = unit->next) { - /* - * Only configuration items are written, measured values and states - * are written to a state file. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWSYSTEM")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", unit->uuid)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", unit->name)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NUMBER", "%d", unit->number)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ACTIVE", "%d", unit->active)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_UUID", "%s", unit->hlt_sensor.uuid)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_STATE", "%d", unit->hlt_sensor.state)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_VALUE", "%d", unit->hlt_sensor.value)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_UUID", "%s", unit->hlt_heater.uuid)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_VALUE", "%d", unit->hlt_heater.value)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_DELAY", "%d", unit->hlt_heater.delay)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_MLTFIRST", "%d", unit->hlt_heater_mltfirst)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_UUID", "%s", unit->mlt_sensor.uuid)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_STATE", "%d", unit->mlt_sensor.state)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_VALUE", "%d", unit->mlt_sensor.value)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_UUID", "%s", unit->mlt_heater.uuid)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_VALUE", "%d", unit->mlt_heater.value)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_DELAY", "%d", unit->mlt_heater.delay)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_UUID", "%s", unit->mlt_pump.uuid)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_VALUE", "%d", unit->mlt_pump.value)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_DELAY", "%d", unit->mlt_pump.delay)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_CYCLE", "%d", unit->pump_cycle)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_REST", "%d", unit->pump_rest)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_PREMASH", "%d", unit->pump_premash)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_ONMASH", "%d", unit->pump_onmash)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_MASHOUT", "%d", unit->pump_mashout)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_ONBOIL", "%d", unit->pump_onboil)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_STOP", "%.3f", unit->pump_stop)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_ADD", "%d", unit->skip_add)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_REMOVE", "%d", unit->skip_remove)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_IODINE", "%d", unit->skip_iodine)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IODINE_TIME", "%d", unit->iodine_time)) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "WHIRLPOOL", "%s", WHIRLPOOL_TYPE[unit->whirlpool])) < 0)) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - if (unit->PID_hlt) { - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KP", "%lf", PID_getKp(unit->PID_hlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KI", "%lf", PID_getKi(unit->PID_hlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KD", "%lf", PID_getKd(unit->PID_hlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_SAMPLETIME", "%d", PID_getSampleTime(unit->PID_hlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_DIRECTION", "%s", PIDDIRECTION[PID_getDirection(unit->PID_hlt)])) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - } - - if (unit->PID_mlt) { - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KP", "%lf", PID_getKp(unit->PID_mlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KI", "%lf", PID_getKi(unit->PID_mlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KD", "%lf", PID_getKd(unit->PID_mlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_SAMPLETIME", "%d", PID_getSampleTime(unit->PID_mlt))) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_DIRECTION", "%s", PIDDIRECTION[PID_getDirection(unit->PID_mlt)])) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - } - - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - } - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - } - - if (Config.devices) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICES")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_DEVICES); -#endif - for (device = Config.devices; device; device = device->next) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICE")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VERSION", "%d", device->version)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", device->uuid)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TYPE", "%s", DEVTYPE[device->type])) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DIRECTION", "%s", DEVDIR[device->direction])) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VALUE", "%d", device->value)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "OFFSET", "%d", device->offset)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRESENT", "%s", DEVPRESENT[device->present])) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "%s", device->address)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SUBDEVICE", "%d", device->subdevice)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "GPIOPIN", "%d", device->gpiopin)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DESCRIPTION", "%s", device->description)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "INUSE", "%d", device->inuse)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COMMENT", "%s", device->comment)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TIMESTAMP", "%d", (int)device->timestamp)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_DEVICES); -#endif - - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - } - -#ifdef USE_SIMULATOR - if (Config.simulator) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "SIMULATOR")) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOM_TEMPERATURE", "%f", Config.simulator->room_temperature)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_TEMPERATURE", "%f", Config.simulator->hlt_temperature)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_TEMP", "%f", Config.simulator->hlt_heater_temp)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_VOLUME", "%d", Config.simulator->hlt_heater_volume)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_POWER", "%d", Config.simulator->hlt_heater_power)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_STATE", "%d", Config.simulator->hlt_heater_state)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_TEMPERATURE", "%f", Config.simulator->mlt_temperature)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_TEMP", "%f", Config.simulator->mlt_heater_temp)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_VOLUME", "%d", Config.simulator->mlt_heater_volume)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_POWER", "%d", Config.simulator->mlt_heater_power)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_STATE", "%d", Config.simulator->mlt_heater_state)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); - return 1; - } - - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); - return 1; - } - } -#endif - - /* - * All done, close any open elements - */ - if ((rc = xmlTextWriterEndDocument(writer)) < 0) { - syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndDocument"); - return 1; - } - xmlFreeTextWriter(writer); - - /* - * Now write the XML configuration - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"brewco.xml"); - - if ((fp = fopen(mypath, "w")) == NULL) { - syslog(LOG_NOTICE, "could not rewrite %s", mypath); - free(mypath); - return 1; - } - free(mypath); - - fprintf(fp, "%s", (const char *) buf->content); - fclose(fp); - xmlBufferFree(buf); - - return 0; -} - - - -int wrconfig(void) -{ - int rc = do_wrconfig(); - syslog(LOG_NOTICE, "Rewritten configuration, rc=%d", rc); - return rc; -} - - - -/* - * Parse one LCD display - */ -int parseLCD(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - int ival; - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLUMNS"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.lcd_cols = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROWS"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.lcd_rows = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%x", &ival) == 1) - Config.lcd_address = ival; - xmlFree(key); - } - cur = cur->next; - } - - return 0; -} - - - -int parseLCDs(xmlDocPtr doc, xmlNodePtr cur) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCD"))) { - parseLCD(doc, cur); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse a brewsystem - */ -int parseBrewsystem(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - int i, ival; - long lval; - float fval; - double kpval, kival, kdval; - units_list *unit, *tmp; - - unit = (units_list *)malloc(sizeof(units_list)); - unit->next = NULL; - unit->version = 1; - unit->uuid = unit->name = NULL; - unit->number = 0; - unit->active = 0; - unit->hlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->hlt_sensor.state = 0; - unit->hlt_sensor.value = 0; - unit->mlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_sensor.state = 0; - unit->mlt_sensor.value = 0; - unit->hlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->hlt_heater.value = 0; - unit->hlt_heater.delay = 0; - unit->mlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_heater.value = 0; - unit->mlt_heater.delay = 0; - unit->mlt_pump.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_pump.value = 0; - unit->mlt_pump.delay = 0; - unit->hlt_heater_mltfirst = 0; - unit->pump_cycle = 7; - unit->pump_rest = 2; - unit->pump_premash = 1; - unit->pump_onmash = 1; - unit->pump_mashout = 0; - unit->pump_onboil = 0; - unit->pump_stop = 90.0; - unit->skip_add = 0; - unit->skip_remove = 0; - unit->skip_iodine = 0; - unit->iodine_time = 90; - unit->whirlpool = 1; - unit->PID_hlt = (pid_var *)malloc(sizeof(pid_var)); - unit->PID_mlt = (pid_var *)malloc(sizeof(pid_var)); - PID_init(unit->PID_hlt, NULL, NULL, NULL, 2, 5, 1, P_DIRECT); - PID_init(unit->PID_mlt, NULL, NULL, NULL, 2, 5, 1, P_DIRECT); - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (xmlStrcmp(key, (const xmlChar *)"1")) { - xmlFree(key); - return 1; - } - unit->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) { - unit->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - unit->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NUMBER"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->number = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ACTIVE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->active = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_UUID"))) { - unit->hlt_sensor.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_STATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->hlt_sensor.state = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->hlt_sensor.value = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_UUID"))) { - unit->hlt_heater.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->hlt_heater.value = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_DELAY"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->hlt_heater.delay = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_MLTFIRST"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->hlt_heater_mltfirst = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_UUID"))) { - unit->mlt_sensor.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_STATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_sensor.state = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_sensor.value = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_UUID"))) { - unit->mlt_heater.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_heater.value = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_DELAY"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_heater.delay = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_UUID"))) { - unit->mlt_pump.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_pump.value = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_DELAY"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->mlt_pump.delay = ival; - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_CYCLE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_cycle = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_REST"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_rest = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_PREMASH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_premash = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_ONMASH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_onmash = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_MASHOUT "))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_mashout = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_ONBOIL"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->pump_onboil = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_STOP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - unit->pump_stop = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_ADD"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->skip_add = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_REMOVE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->skip_remove = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_IODINE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->skip_iodine = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"IODINE_TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - unit->iodine_time = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"WHIRLPOOL"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 2; i++) { - if (! xmlStrcmp(key, (const xmlChar *)WHIRLPOOL_TYPE[i])) { - unit->whirlpool = i; - break; - } - } - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kpval); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KI"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kival); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KD"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kdval); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_SAMPLETIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%ld", &lval) == 1) { - PID_setSampleTime(unit->PID_hlt, lval); - PID_setTunings(unit->PID_hlt, kpval, kival, kdval); - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_DIRECTION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 2; i++) { - if (! xmlStrcmp(key, (const xmlChar *)PIDDIRECTION[i])) { - PID_setDirection(unit->PID_hlt, i); - break; - } - } - xmlFree(key); - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kpval); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KI"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kival); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KD"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - sscanf((const char *)key, "%lf", &kdval); - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_SAMPLETIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%ld", &lval) == 1) { - PID_setSampleTime(unit->PID_mlt, lval); - PID_setTunings(unit->PID_mlt, kpval, kival, kdval); - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_DIRECTION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 2; i++) { - if (! xmlStrcmp(key, (const xmlChar *)PIDDIRECTION[i])) { - PID_setDirection(unit->PID_mlt, i); - break; - } - } - xmlFree(key); - } - - cur = cur->next; - } - - if (Config.units == NULL) { - Config.units = unit; - } else { - for (tmp = Config.units; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = unit; - break; - } - } - } - - return 0; -} - - - -int parseBrewsystems(xmlDocPtr doc, xmlNodePtr cur) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BREWSYSTEM"))) { - parseBrewsystem(doc, cur); - } - cur = cur->next; - } - return 0; -} - - -int parseDevice(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - devices_list *device, *tmp; - int i, ival; - - device = (devices_list *)malloc(sizeof(devices_list)); - device->next = NULL; - device->version = 1; - device->uuid = device->address = device->description = device->comment = NULL; - device->type = device->direction = device->present = device->subdevice = device->inuse = device->offset = 0; - device->gpiopin = -1; - device->timestamp = (time_t)0; - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (xmlStrcmp(key, (const xmlChar *)"1")) { - xmlFree(key); - return 1; - } - device->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) { - device->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 8; i++) { - if (! xmlStrcmp(key, (const xmlChar *)DEVTYPE[i])) { - device->type = i; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DIRECTION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 7; i++) { - if (! xmlStrcmp(key, (const xmlChar *)DEVDIR[i])) { - device->direction = i; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"VALUE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->value = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"OFFSET"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->offset = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRESENT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - for (i = 0; i < 4; i++) { - if (! xmlStrcmp(key, (const xmlChar *)DEVPRESENT[i])) { - device->present = i; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) { - device->address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SUBDEVICE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->subdevice = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"GPIOPIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->gpiopin = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DESCRIPTION"))) { - device->description = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"INUSE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->inuse = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COMMENT"))) { - device->comment = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIMESTAMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - device->timestamp = (time_t)ival; - xmlFree(key); - } - - cur = cur->next; - } - - if (Config.devices == NULL) { - Config.devices = device; - } else { - for (tmp = Config.devices; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = device; - break; - } - } - } - - return 0; -} - - - -int parseDevices(xmlDocPtr doc, xmlNodePtr cur) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICE"))) { - parseDevice(doc, cur); - } - cur = cur->next; - } - return 0; -} - - - -#ifdef USE_SIMULATOR -int parseSimulator(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - int ival; - float fval; - - /* - * First time, allocate memory and set defaults. - */ - if (! Config.simulator) { - Config.simulator = (simulator_var *)malloc(sizeof(simulator_var)); - Config.simulator->room_temperature = Config.simulator->hlt_temperature = Config.simulator->hlt_heater_temp = \ - Config.simulator->mlt_temperature = Config.simulator->mlt_heater_temp = 20.0; - Config.simulator->hlt_heater_volume = Config.simulator->mlt_heater_volume = 20; - Config.simulator->hlt_heater_power = Config.simulator->mlt_heater_power = 2000; - Config.simulator->hlt_heater_state = Config.simulator->mlt_heater_state = 0; - } - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOM_TEMPERATURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - Config.simulator->room_temperature = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_TEMPERATURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - Config.simulator->hlt_temperature = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - Config.simulator->hlt_heater_temp = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_VOLUME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->hlt_heater_volume = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_POWER"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->hlt_heater_power = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_STATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->hlt_heater_state = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_TEMPERATURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - Config.simulator->mlt_temperature = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - Config.simulator->mlt_heater_temp = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_VOLUME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->mlt_heater_volume = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_POWER"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->mlt_heater_power = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_STATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.simulator->mlt_heater_state = ival; - xmlFree(key); - } - cur = cur->next; - } - - return 0; -} -#endif - - - -int rdconfig(void) -{ - int i, ival, rc = 0; - char *mypath, *fpath, *tpath; - xmlDocPtr doc; - xmlNodePtr cur; - xmlChar *key; - - killconfig(); - - /* - * Search config file - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"brewco.xml"); - - /* - * Make upto 10 backups of the configuration. - */ - fpath = calloc(PATH_MAX, sizeof(char)); - tpath = calloc(PATH_MAX, sizeof(char)); - - for (i = 9; i > 0; i--) { - snprintf(tpath, PATH_MAX, "%s.%d", mypath, i+1); - snprintf(fpath, PATH_MAX, "%s.%d", mypath, i); - if (file_exist(fpath, R_OK) == 0) { - unlink(tpath); - if (file_cp(fpath, tpath)) { - syslog(LOG_NOTICE, "rdconfig file_cp(%s, %s): %s", fpath, tpath, strerror(errno)); - } - } - } - snprintf(tpath, PATH_MAX, "%s.1", mypath); - snprintf(fpath, PATH_MAX, "%s", mypath); - if (file_exist(fpath, R_OK) == 0) { - unlink(tpath); - if (file_cp(fpath, tpath)) { - syslog(LOG_NOTICE, "rdconfig file_cp(%s, %s): %s", fpath, tpath, strerror(errno)); - } - } - free(fpath); - free(tpath); - - if ((doc = xmlParseFile(mypath)) == NULL) { - /* - * No config file, create a fresh one - */ - syslog(LOG_NOTICE, "rdconfig: %s not found, creating", mypath); - wrconfig(); - - if ((doc = xmlParseFile(mypath)) == NULL) { - syslog(LOG_NOTICE, "rdconfig: could not create %s", mypath); - free(mypath); - return 1; - } - } - syslog(LOG_NOTICE, "rdconfig: using %s", mypath); - - if ((cur = xmlDocGetRootElement(doc)) == NULL) { - syslog(LOG_NOTICE, "XML file %s empty.", mypath); - xmlFreeDoc(doc); - return 1; - } - if (xmlStrcmp(cur->name, (const xmlChar*)"BREWCO")) { - syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath); - xmlFreeDoc(doc); - return 1; - } - - /* - * Parse configuration - */ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (xmlStrcmp(key, (const xmlChar *)"1")) { - xmlFree(key); - syslog(LOG_NOTICE, "XML file %s is not a valid version", mypath); - return 1; - } - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - Config.name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - Config.my_port = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMPFORMAT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - Config.tempFormat = key[0]; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOMTEMP_UUID"))) { - if (Config.roomtemp == NULL) { - Config.roomtemp = (sensor_var *)malloc(sizeof(sensor_var)); - Config.roomtemp->uuid[0] = '\0'; - Config.roomtemp->state = 1; // missing - Config.roomtemp->value = 0; - } - snprintf(Config.roomtemp->uuid, 36, "%s", xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCDS"))) { - parseLCDs(doc, cur); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BREWSYSTEMS"))) { - parseBrewsystems(doc, cur); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICES"))) { - parseDevices(doc, cur); - } -#ifdef USE_SIMULATOR - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SIMULATOR"))) { - parseSimulator(doc, cur); - } -#endif - cur = cur->next; - } - xmlFreeDoc(doc); - - free(mypath); - mypath = NULL; - -#ifdef USE_SIMULATOR - /* - * If we didn't find any simulator values, initialize a new simulator. - */ - if (! Config.simulator) { - Config.simulator = (simulator_var *)malloc(sizeof(simulator_var)); - syslog(LOG_NOTICE, "rdconfig() init a new simulator"); - Config.simulator->room_temperature = Config.simulator->hlt_temperature = Config.simulator->hlt_heater_temp = \ - Config.simulator->mlt_temperature = Config.simulator->mlt_heater_temp = 20.0; - Config.simulator->hlt_heater_volume = Config.simulator->mlt_heater_volume = 20; - Config.simulator->hlt_heater_power = Config.simulator->mlt_heater_power = 2000; - Config.simulator->hlt_heater_state = Config.simulator->mlt_heater_state = 0; - } -#endif - - return rc; -} - - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdconfig.h --- a/brewco/rdconfig.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#ifndef RDCONFIG_H -#define RDCONFIG_H - - -void killconfig(void); -int rdconfig(void); -int wrconfig(void); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdrecipes.c --- a/brewco/rdrecipes.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,655 +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 "rdrecipes.h" -#include "util.h" -#include "xutil.h" - -extern int debug; -extern char *etcpath; - -a_recipe *recipes = NULL; - - -const char SKIPYN[2][4] = { "NO", "YES" }; - - -#define MY_ENCODING "utf-8" - - -int do_wrrecipes(void); -int do_wrrecipes(void) -{ - int i, rc = 0; - FILE *fp; - char *mypath = NULL; - a_recipe *recipe; - xmlTextWriterPtr writer; - xmlBufferPtr buf; - - /* - * Create a new XML buffer, to which the XML document will be written - */ - if ((buf = xmlBufferCreate()) == NULL) { - syslog(LOG_NOTICE, "wrrecipes: error creating the xml buffer"); - return 1; - } - - /* - * Create a new XmlWriter for memory, with no compression. - */ - if ((writer = xmlNewTextWriterMemory(buf, 0)) == NULL) { - syslog(LOG_NOTICE, "wrrecipes: error creating the xml writer"); - return 1; - } - - /* - * Use indentation instead of one long line - */ - if ((rc = xmlTextWriterSetIndent(writer, 2)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error setting Indent"); - return 1; - } - - /* - * Start the document with the xml default for the version, - * encoding ISO 8859-1 and the default for the standalone - * declaration. - */ - if ((rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartDocument"); - return 1; - } - - /* - * Start an element named "BREWCO". Since thist is the first - * element, this will be the root element of the document. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWCO")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "RECIPES")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - - for (recipe = recipes; recipe; recipe = recipe->next) { - - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "RECIPE")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", recipe->uuid)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CODE", "%s", recipe->code)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", recipe->name)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BOILTIME", "%d", recipe->boiltime)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COOLTO", "%f", recipe->coolto)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "STARTTIME", "%d", (int)recipe->starttime)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENDTIME", "%d", (int)recipe->endtime)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - - /* - * 8 Mash steps - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "MASHSTEPS")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - for (i =0; i < 8; i++) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "MASHSTEP")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", recipe->mash[i].name)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MIN", "%d", recipe->mash[i].min)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAX", "%d", recipe->mash[i].max)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CANSKIP", "%s", recipe->mash[i].canskip ? "YES":"NO")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SETPOINT", "%f", recipe->mash[i].setpoint)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP", "%s", recipe->mash[i].skip ? "YES":"NO")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DURATION", "%d", recipe->mash[i].duration)) < 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) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * 10 Hop additions - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "HOPADDITIONS")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - for (i = 0; i < 10; i++) { - 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) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * 3 Hop stands - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "HOPSTANDS")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - for (i = 0; i < 3; i++) { - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "HOPSTAND")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", recipe->hopstand[i].name)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MIN", "%d", recipe->hopstand[i].min)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAX", "%d", recipe->hopstand[i].max)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HOLD", "%s", recipe->hopstand[i].hold ? "YES":"NO")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SETPOINT", "%f", recipe->hopstand[i].setpoint)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP", "%s", recipe->hopstand[i].skip ? "YES":"NO")) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DURATION", "%d", recipe->hopstand[i].duration)) < 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) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * Close the element named RECIPE. - */ - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - } - /* - * Close the element named RECIPES. - */ - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * All done, close any open elements - */ - if ((rc = xmlTextWriterEndDocument(writer)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndDocument"); - return 1; - } - xmlFreeTextWriter(writer); - - /* - * Now write the XML recipes - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"recipes.xml"); - - if (debug) - fprintf(stdout, "Writing %s\n", mypath); - - if ((fp = fopen(mypath, "w")) == NULL) { - syslog(LOG_NOTICE, "could not rewrite %s", mypath); - free(mypath); - return 1; - } - free(mypath); - - fprintf(fp, "%s", (const char *) buf->content); - fclose(fp); - xmlBufferFree(buf); - - return 0; -} - - - -int wrrecipes(void) -{ - int rc; - - rc = do_wrrecipes(); - syslog(LOG_NOTICE, "Rewritten recipes, rc=%d", rc); - return rc; -} - - - -int parseRecipe(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - xmlNodePtr s1cur, s2cur; - a_recipe *recipe, *tmp; - int i, j, ival; - float fval; - - recipe = (a_recipe *)malloc(sizeof(a_recipe)); - memset(recipe, 0, sizeof(a_recipe)); - recipe->next = NULL; - recipe->coolto = 20.0; - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) { - recipe->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CODE"))) { - recipe->code = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - recipe->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BOILTIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->boiltime = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COOLTO"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - recipe->coolto = fval; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STARTTIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->starttime = (time_t)ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ENDTIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->endtime = (time_t)ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MASHSTEPS"))) { - s1cur = cur->xmlChildrenNode; - i = 0; - while (s1cur != NULL) { - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"MASHSTEP"))) { - s2cur = s1cur->xmlChildrenNode; - while (s2cur != NULL) { - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"NAME"))) { - recipe->mash[i].name = (char *)xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"MIN"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->mash[i].min = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"MAX"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->mash[i].max = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"CANSKIP"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - for (j = 0; j < 2; j++) { - if (! xmlStrcmp(key, (const xmlChar *)SKIPYN[j])) { - recipe->mash[i].canskip = j; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"SETPOINT"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - recipe->mash[i].setpoint = fval; - xmlFree(key); - } - 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->mash[i].skip = j; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"DURATION"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->mash[i].duration = ival; - xmlFree(key); - } - s2cur = s2cur->next; - } - i++; - } - s1cur = s1cur->next; - } - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HOPADDITIONS"))) { - s1cur = cur->xmlChildrenNode; - i = 0; - while (s1cur != NULL) { - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"HOPADDITION"))) { - s2cur = s1cur->xmlChildrenNode; - while (s2cur != NULL) { - 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) - recipe->hops[i].boiltime = ival; - xmlFree(key); - } - s2cur = s2cur->next; - } - i++; - } - s1cur = s1cur->next; - } - } - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HOPSTANDS"))) { - s1cur = cur->xmlChildrenNode; - i = 0; - while (s1cur != NULL) { - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"HOPSTAND"))) { - s2cur = s1cur->xmlChildrenNode; - while (s2cur != NULL) { - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"NAME"))) { - recipe->hopstand[i].name = (char *)xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"MIN"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->hopstand[i].min = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"MAX"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->hopstand[i].max = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"HOLD"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - for (j = 0; j < 2; j++) { - if (! xmlStrcmp(key, (const xmlChar *)SKIPYN[j])) { - recipe->hopstand[i].hold = j; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"SETPOINT"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &fval) == 1) - recipe->hopstand[i].setpoint = fval; - xmlFree(key); - } - 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->hopstand[i].skip = j; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s2cur->name, (const xmlChar *)"DURATION"))) { - key = xmlNodeListGetString(doc, s2cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->hopstand[i].duration = ival; - xmlFree(key); - } - s2cur = s2cur->next; - } - i++; - } - s1cur = s1cur->next; - } - } - cur = cur->next; - } - - if (recipes == NULL) { - recipes = recipe; - } else { - for (tmp = recipes; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = recipe; - break; - } - } - } - - return 0; -} - - - -int parseRecipes(xmlDocPtr doc, xmlNodePtr cur) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"RECIPE"))) { - parseRecipe(doc, cur); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Returns: - * 0 - All is well, recipes loaded. - * 1 - Something went wrong - */ -int rdrecipes(void) -{ - int i; - char *mypath; - xmlDocPtr doc; - xmlNodePtr cur; - a_recipe *recipe; - - /* - * Search config file - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"recipes.xml"); - - /* - * Free possible old recipes list - */ - for (recipe = recipes; recipe; recipe = recipe->next) { - if (recipe->uuid) - free(recipe->uuid); - if (recipe->code) - free(recipe->code); - if (recipe->name) - free(recipe->name); - for (i = 0; i < 8; i++) - if (recipe->mash[i].name) - free(recipe->mash[i].name); - for (i = 0; i < 10; i++) - if (recipe->hops[i].name) - free(recipe->hops[i].name); - for (i = 0; i < 3; i++) - if (recipe->hopstand[i].name) - free(recipe->hopstand[i].name); - free(recipe); - } - recipes = NULL; - - /* - * See if we have a recipes file. - */ - if (file_exist(mypath, W_OK)) { - syslog(LOG_NOTICE, "rdrecipes: %s not found, good.", mypath); - free(mypath); - return 0; - } - - if ((doc = xmlParseFile(mypath)) == NULL) { - syslog(LOG_NOTICE, "rdrecipes: %s not found, we may need some.", mypath); - free(mypath); - return 0; - } - syslog(LOG_NOTICE, "rdrecipes: using %s", mypath); - - if ((cur = xmlDocGetRootElement(doc)) == NULL) { - syslog(LOG_NOTICE, "XML file %s empty.", mypath); - xmlFreeDoc(doc); - return 1; - } - if (xmlStrcmp(cur->name, (const xmlChar*)"BREWCO")) { - syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath); - xmlFreeDoc(doc); - return 1; - } - - /* - * Parse recipes - */ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"RECIPES"))) { - parseRecipes(doc, cur); - } - cur = cur->next; - } - xmlFreeDoc(doc); - - free(mypath); - mypath = NULL; - - return 0; -} - - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdrecipes.h --- a/brewco/rdrecipes.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#ifndef _RDRECIPES_H -#define _RDRECIPES_H - - -int rdrecipes(void); -int wrrecipes(void); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdsession.c --- a/brewco/rdsession.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,327 +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 "rdsession.h" -#include "util.h" -#include "xutil.h" - -extern int debug; -extern char *etcpath; - - -const char BREWSTEP[16][11] = { "NA", "BREWINIT", "WATERCHECK", "PUMPPRIME", "WAITSTART", - "PREMASH", "MASHING", "REMOVE", "PREBOIL", "BOIL", - "BOILDONE", "COOLING", "HOPSTAND", "WHIRLPOOL", "CLEANUP", - "BREWDONE" }; -const char MASHSTEP[8][11] = { "MASH-IN", "PHYTASE", "GLUCANASE", "PROTEASE", "B-AMYLASE", "A-AMYLASE1", "A-AMYLASE2", "MASH-OUT" }; - -#define MY_ENCODING "utf-8" - - -char *brewstep_name(int val) -{ - static char text[41]; - - snprintf(text, 20, BREWSTEP[val]); - return text; -} - - -int do_wrsession(brew_session *brew); -int do_wrsession(brew_session *brew) -{ - int rc = 0; - FILE *fp; - char *mypath = NULL; - xmlTextWriterPtr writer; - xmlBufferPtr buf; - - /* - * Create a new XML buffer, to which the XML document will be written - */ - if ((buf = xmlBufferCreate()) == NULL) { - syslog(LOG_NOTICE, "wrsession: error creating the xml buffer"); - return 1; - } - - /* - * Create a new XmlWriter for memory, with no compression. - */ - if ((writer = xmlNewTextWriterMemory(buf, 0)) == NULL) { - syslog(LOG_NOTICE, "wrsession: error creating the xml writer"); - return 1; - } - - /* - * Use indentation instead of one long line - */ - if ((rc = xmlTextWriterSetIndent(writer, 2)) < 0) { - syslog(LOG_NOTICE, "wrsession: error setting Indent"); - return 1; - } - - /* - * Start the document with the xml default for the version, - * encoding ISO 8859-1 and the default for the standalone - * declaration. - */ - if ((rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterStartDocument"); - return 1; - } - - /* - * Start an element named "BREWCO". Since thist is the first - * element, this will be the root element of the document. - */ - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWCO")) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterStartElement"); - return 1; - } - if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREW")) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterStartElement"); - return 1; - } - - /* - * Add an attribute with name "VERSION" and value "1" to BRWCO. - */ - if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID_RECIPE", "%s", brew->uuid_recipe)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID_UNIT", "%s", brew->uuid_unit)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", brew->name)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteFormatElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BREWSTEP", "%s", BREWSTEP[brew->brewstep])) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MASHSTEP", "%s", MASHSTEP[brew->mashstep])) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TIMEOUT", "%d", brew->timeout)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BOILTIMER", "%d", brew->boiltimer)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "STARTTIME", "%d", (int)brew->starttime)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENDTIME", "%d", (int)brew->endtime)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterWriteElement"); - return 1; - } - - /* - * Close the element named BREW. - */ - if ((rc = xmlTextWriterEndElement(writer)) < 0) { - syslog(LOG_NOTICE, "wrrecipes: error at xmlTextWriterEndElement"); - return 1; - } - - /* - * All done, close any open elements - */ - if ((rc = xmlTextWriterEndDocument(writer)) < 0) { - syslog(LOG_NOTICE, "wrsession: error at xmlTextWriterEndDocument"); - return 1; - } - xmlFreeTextWriter(writer); - - /* - * Now write the XML configuration - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"brewing.xml"); - - if (debug) - fprintf(stdout, "Writing %s\n", mypath); - - if ((fp = fopen(mypath, "w")) == NULL) { - syslog(LOG_NOTICE, "could not rewrite %s", mypath); - free(mypath); - return 1; - } - free(mypath); - - fprintf(fp, "%s", (const char *) buf->content); - fclose(fp); - xmlBufferFree(buf); - - return 0; -} - - - -int wrsession(brew_session *brew) -{ - int rc; - - rc = do_wrsession(brew); -// syslog(LOG_NOTICE, "Rewritten brewsession, rc=%d", rc); - return rc; -} - - - -/* - * Returns: - * 0 - All is well, session loaded. - * 1 - Something went wrong - * -1 - No brew session available - */ -int rdsession(brew_session *brew) -{ - int i, ival; - char *mypath; - xmlDocPtr doc; - xmlNodePtr cur, s1cur; - xmlChar *key; - - /* - * Search config file - */ - mypath = xstrcpy(etcpath); - mypath = xstrcat(mypath, (char *)"brewing.xml"); - - /* - * See if we have a brewing state file. - */ - if (file_exist(mypath, W_OK)) { - syslog(LOG_NOTICE, "rdsession: %s not found, good.", mypath); - free(mypath); - return -1; - } - - if ((doc = xmlParseFile(mypath)) == NULL) { - syslog(LOG_NOTICE, "rdsession: %s not found, should not happen.", mypath); - free(mypath); - return -1; - } - syslog(LOG_NOTICE, "rdsession: using %s", mypath); - - if ((cur = xmlDocGetRootElement(doc)) == NULL) { - syslog(LOG_NOTICE, "XML file %s empty.", mypath); - xmlFreeDoc(doc); - return 1; - } - if (xmlStrcmp(cur->name, (const xmlChar*)"BREWCO")) { - syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath); - xmlFreeDoc(doc); - return 1; - } - - /* - * Parse session - */ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - - if ((! xmlStrcmp(cur->name, (const xmlChar*)"BREW"))) { - s1cur = cur->xmlChildrenNode; - while (s1cur != NULL) { - - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"UUID_RECIPE"))) { - brew->uuid_recipe = (char *)xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"UUID_UNIT"))) { - brew->uuid_unit = (char *)xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"NAME"))) { - brew->name = (char *)xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"BREWSTEP"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - for (i = 0; i < 15; i++) { - if (! xmlStrcmp(key, (const xmlChar *)BREWSTEP[i])) { - brew->brewstep = i; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"MASHSTEP"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - for (i = 0; i < 8; i++) { - if (! xmlStrcmp(key, (const xmlChar *)MASHSTEP[i])) { - brew->mashstep = i; - break; - } - } - xmlFree(key); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"TIMEOUT"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - brew->timeout = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"BOILTIMER"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - brew->boiltimer = ival; - xmlFree(key); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"STARTTIME"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - brew->starttime = (time_t)ival; - xmlFree(key); - } - if ((!xmlStrcmp(s1cur->name, (const xmlChar *)"ENDTIME"))) { - key = xmlNodeListGetString(doc, s1cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - brew->endtime = (time_t)ival; - xmlFree(key); - } - s1cur = s1cur->next; - } - } - cur = cur->next; - } - xmlFreeDoc(doc); - - free(mypath); - mypath = NULL; - - return 0; -} - - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/rdsession.h --- a/brewco/rdsession.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#ifndef _RDSESSION_H -#define _RDSESSION_H - - -char *brewstep_name(int); -int rdsession(brew_session *brew); -int wrsession(brew_session *brew); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/setup.c --- a/brewco/setup.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1523 +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 "slcd.h" -#include "setup.h" -#include "prompt.h" -#include "xutil.h" -#include "keyboard.h" -#include "rdconfig.h" -#include "rdrecipes.h" - - -extern int my_shutdown; -extern int debug; -extern sys_config Config; -extern int lcdHandle; -extern int slcdHandle; -extern a_recipe *recipes; - - - -void editFloat(float *value, float low, float high, char *text) -{ - int key; - float new = *value; - char pmpt[81]; - - prompt(0, NULL); - prompt(133, NULL); - - for (;;) { - snprintf(pmpt, Config.lcd_cols + 1, "%s: %5.1f\001", text, new); - prompt(200, pmpt); - if (new == low) - prompt(404, NULL); - else if (new == high) - prompt(402, NULL); - else - prompt(403, NULL); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) - return; - if (key == KEY_UP) { - new = new + 0.5; - if (new > high) - new = high; - } - if (key == KEY_DOWN) { - new = new - 0.5; - if (new < low) - new = low; - } - if (key == KEY_ENTER) { - *value = new; - return; - } - } -} - - - -void editDouble(double *value, double low, double high, char *text) -{ - int key; - double new = *value; - char pmpt[81]; - - prompt(0, NULL); - prompt(138, NULL); - - for (;;) { - snprintf(pmpt, Config.lcd_cols + 1, "%s: %5.2lf", text, new); - prompt(200, pmpt); - if (new == low) - prompt(404, NULL); - else if (new == high) - prompt(402, NULL); - else - prompt(403, NULL); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) - return; - if (key == KEY_UP) { - new = new + 0.5; - if (new > high) - new = high; - } - if (key == KEY_DOWN) { - new = new - 0.5; - if (new < low) - new = low; - } - if (key == KEY_ENTER) { - *value = new; - return; - } - } -} - - - -void editInteger(int *value, int low, int high, int step, char *text, char *text2) -{ - int key, new = *value; - char pmpt[81]; - - prompt(0, NULL); - prompt(134, NULL); - - for (;;) { - snprintf(pmpt, Config.lcd_cols + 1, "%s: %3d %s", text, new, text2); - prompt(200, pmpt); - if (new == low) - prompt(404, NULL); - else if (new == high) - prompt(402, NULL); - else - prompt(403, NULL); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) - return; - if (key == KEY_UP) { - new += step; - if (new > high) - new = high; - } - if (key == KEY_DOWN) { - new -= step; - if (new < low) - new = low; - } - if (key == KEY_ENTER) { - *value = new; - return; - } - } -} - - - -void togglePmpts(int *value, char *text, int pno, char *pmpt1, char *pmpt2) -{ - int key, new = *value; - char pmpt[81]; - - prompt(0, NULL); - prompt(pno, NULL); - - for (;;) { - - snprintf(pmpt, Config.lcd_cols + 1, "%s: %s", text, new ? pmpt1:pmpt2); - prompt(200, pmpt); - if (new) { - prompt(404, NULL); - } else { - prompt(402, NULL); - } - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) - return; - if ((key == KEY_UP) && new) - new = 0; - else if ((key == KEY_DOWN) && (new == 0)) - new = 1; - if (key == KEY_ENTER) { - *value = new; - return; - } - } -} - - - -void toggleYesNo(int *value, char *text) -{ - togglePmpts(value, text, 132, (char *)"Yes", (char *)"No "); -} - - - -void toggleDirection(int *value, char *text) -{ - togglePmpts(value, text, 137, (char *)"Reverse", (char *)"Direct "); -} - - - -void editName(char *name, char *text) -{ - char pmpt[81]; - int i, x = 0, key, val; - - if (debug) - fprintf(stdout, "editName(%s)\n", name); - - prompt(0, NULL); - prompt(131, NULL); /* " Change Name " */ - prompt(417, NULL); /* " up dwn next ok " */ - - for (;;) { - snprintf(pmpt, Config.lcd_cols + 1, " "); - prompt(200, pmpt); -#ifdef HAVE_WIRINGPI_H - lcdPosition(lcdHandle, x, 1); - lcdPutchar(lcdHandle, '*'); -#endif - slcdPosition(slcdHandle, x, 1); - slcdPutchar(slcdHandle, '*'); - snprintf(pmpt, Config.lcd_cols + 1, "%s", name); - prompt(300, pmpt); - - key = keywait(); - - if ((key == KEY_ENTER) || my_shutdown) { - if (debug) - fprintf(stdout, "End editName(%s)\n", name); - for (i = strlen(name) -1; i > 1; i--) { - if (name[i] != ' ') - break; - name[i] = '\0'; - } - if (debug) - fprintf(stdout, "End editName(%s)\n", name); - return; - } - if (key == KEY_RETURN) { - if (x < 19) - x++; - else - x = 0; - if (debug) - fprintf(stdout, "editName: strlen=%d x=%d\n", (int)strlen(name) - 1, x); - if (x > ((int)strlen(name) - 1)) { - name[x + 1] = '\0'; - name[x] = ' '; - } - } - if (key == KEY_UP || key == KEY_DOWN) { - val = name[x]; - if ((key == KEY_UP) && (val < 126)) - val++; - if ((key == KEY_DOWN) && (val > 32)) - val--; - name[x] = val; - } - } -} - - - -void editPID(pid_var *pid) -{ - int idx = 1, key, val; - char pmpt[81]; - double Kp, Ki, Kd; - - if (debug) - fprintf(stdout, "editPID()\n"); - - for (;;) { - prompt(0, NULL); - prompt(192, NULL); - - if (idx == 1) - prompt(402, NULL); - else if (idx == 5) - prompt(404, NULL); - else - prompt(403, NULL); - - switch (idx) { - case 1: snprintf(pmpt, Config.lcd_cols + 1, "PID Kp: %5.2f", PID_getKp(pid)); - break; - case 2: snprintf(pmpt, Config.lcd_cols + 1, "PID Ki: %5.2f", PID_getKi(pid)); - break; - case 3: snprintf(pmpt, Config.lcd_cols + 1, "PID Kd: %5.2f", PID_getKd(pid)); - break; - case 4: snprintf(pmpt, Config.lcd_cols + 1, "SampleTime: %3d mSec", PID_getSampleTime(pid)); - break; - case 5: snprintf(pmpt, Config.lcd_cols + 1, "Direction: %s", PID_getDirection(pid) ? (char *)"Reverse" : (char *)"Direct"); - break; - } - prompt(200, pmpt); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) { - if (debug) - fprintf(stdout, "End editPID\n"); - return; - } - - if ((key == KEY_UP) && (idx > 1)) - idx--; - if ((key == KEY_DOWN) && (idx < 5)) - idx++; - - if (key == KEY_ENTER) { - - Kp = PID_getKp(pid); - Ki = PID_getKi(pid); - Kd = PID_getKd(pid); - - switch(idx) { - case 1: editDouble(&Kp, 0.5, 50, (char *)"PID Kp"); - PID_setTunings(pid, Kp, Ki, Kd); - break; - case 2: editDouble(&Ki, 0.5, 50, (char *)"PID Ki"); - PID_setTunings(pid, Kp, Ki, Kd); - break; - case 3: editDouble(&Kd, 0.5, 50, (char *)"PID Kd"); - PID_setTunings(pid, Kp, Ki, Kd); - break; - case 4: val = PID_getSampleTime(pid); - editInteger(&val, 50, 500, 10, (char *)"SampleTime", (char *)"mSec"); - PID_setSampleTime(pid, val); - break; - case 5: val = PID_getDirection(pid); - toggleDirection(&val, (char *)"Direction"); - PID_setDirection(pid, val); - break; - } - } - } -} - - - -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]; - int i, old, choices, idx = 1, key; - devices_list *device; - - if (debug) - fprintf(stdout, "editSensor(%s, %s)\n", uuid, text); - - old = 1; // 1d0e5bb8-7408-48b9-abb4-e9041d7b99fe - if ((i = strcmp((char *)"00000000-0000-0000-0000-000000000000", uuid))) { - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_IN_ANALOG) { - old++; - if (strcmp(device->uuid, uuid) == 0) - break; - } - } - } - - if (debug) - fprintf(stdout, "editSensor(%s) old sensor index=%d\n", text, old); - - for (;;) { - prompt(0, NULL); - snprintf(pmpt, Config.lcd_cols + 1, "Edit %s", text); - prompt(100, pmpt); - - /* - * Count valid sensors - */ - choices = 1; - if (old == 1) { - snprintf(pmpt, Config.lcd_cols + 1, "N/A"); - } - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_IN_ANALOG) { - choices++; - if (choices == old) { - snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description); - } - } - } - prompt(200, pmpt); /* Display current sensor */ - i = 1; - if (idx == 1) { - snprintf(pmpt, Config.lcd_cols + 1, "N/A"); - } else { - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_IN_ANALOG) { - i++; - if (i == idx) { - snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description); - } - } - } - } - prompt(300, pmpt); /* Display possible new sensor */ - - - if (choices == 1) - prompt(405, NULL); - else if (idx == 1) - prompt(402, NULL); - else if (idx == choices) - prompt(404, NULL); - else - prompt(403, NULL); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) { - if (debug) - fprintf(stdout, "End editSensor\n"); - return; - } - - if ((key == KEY_UP) && (idx > 1)) - idx--; - if ((key == KEY_DOWN) && (idx < choices)) - idx++; - - if ((key == KEY_ENTER) && (idx != old)) { - /* - * Select new sensor. - */ - if (idx == 1) { - /* - * Disable the sensor - */ - strncpy(uuid, (char *)"00000000-0000-0000-0000-000000000000", 36); - old = idx; - } else { - i = 1; - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_IN_ANALOG) { - i++; - if (i == idx) { - strncpy(uuid, device->uuid, 36); - break; - } - } - } - old = idx; - } - } - } -} - - - -void editRelay(char *uuid, char *text) -{ - char pmpt[81]; - int i, old, choices, idx = 1, key; - devices_list *device; - - if (debug) - fprintf(stdout, "editRelay(%s, %s)\n", uuid, text); - - old = 1; // 1d0e5bb8-7408-48b9-abb4-e9041d7b99fe - if ((i = strcmp((char *)"00000000-0000-0000-0000-000000000000", uuid))) { - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_OUT_ANALOG) { - old++; - if (strcmp(device->uuid, uuid) == 0) - break; - } - } - } - - if (debug) - fprintf(stdout, "editRelay(%s) old sensor index=%d\n", text, old); - - for (;;) { - prompt(0, NULL); - snprintf(pmpt, Config.lcd_cols + 1, "Edit %s", text); - prompt(100, pmpt); - - /* - * Count valid sensors - */ - choices = 1; - if (old == 1) { - snprintf(pmpt, Config.lcd_cols + 1, "N/A"); - } - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_OUT_ANALOG) { - choices++; - if (choices == old) { - snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description); - } - } - } - prompt(200, pmpt); /* Display current relay */ - i = 1; - if (idx == 1) { - snprintf(pmpt, Config.lcd_cols + 1, "N/A"); - } else { - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_OUT_ANALOG) { - i++; - if (i == idx) { - snprintf(pmpt, Config.lcd_cols + 1, "%s", device->description); - } - } - } - } - prompt(300, pmpt); /* Display possible new relay */ - - if (choices == 1) - prompt(405, NULL); - else if (idx == 1) - prompt(402, NULL); - else if (idx == choices) - prompt(404, NULL); - else - prompt(403, NULL); - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) { - if (debug) - fprintf(stdout, "End editRelay\n"); - return; - } - - if ((key == KEY_UP) && (idx > 1)) - idx--; - if ((key == KEY_DOWN) && (idx < choices)) - idx++; - - if ((key == KEY_ENTER) && (idx != old)) { - /* - * Select new output. - */ - if (idx == 1) { - /* - * Disable the output - */ - strncpy(uuid, (char *)"00000000-0000-0000-0000-000000000000", 36); - old = idx; - } else { - i = 1; - for (device = Config.devices; device; device = device->next) { - if (device->direction == DEVDIR_OUT_ANALOG) { - i++; - if (i == idx) { - strncpy(uuid, device->uuid, 36); - break; - } - } - } - old = idx; - } - } - } -} - - - -/* - * Edit a single unit - */ -void editUnit(units_list *unit) -{ - int idx = 1, key; - char pmpt[81], *uuid, *name; - uLong ocrc, ncrc; - - if (debug) - fprintf(stdout, "Start edit brewsystem %d %s\n", unit->number, unit->uuid); - - prompt(0, NULL); - ncrc = ocrc = crc32(0L, Z_NULL, 0); - ocrc = crc32(ocrc, (const Bytef *) unit, sizeof(units_list)); - - for (;;) { - - prompt(0, NULL); - prompt(193, NULL); - - if (idx == 1) - prompt(402, NULL); - else if (idx == 21) - prompt(404, NULL); - else - prompt(403, NULL); - - switch (idx) { // 12345678901234567890 - case 1: snprintf(pmpt, Config.lcd_cols + 1, "Unit name:"); - prompt(200, pmpt); - snprintf(pmpt, Config.lcd_cols + 1, "%s", unit->name); - prompt(300, pmpt); - break; - case 2: snprintf(pmpt, Config.lcd_cols + 1, " HLT sensor setup"); - prompt(200, pmpt); - break; - case 3: snprintf(pmpt, Config.lcd_cols + 1, " HLT heater setup"); - prompt(200, pmpt); - break; - case 4: snprintf(pmpt, Config.lcd_cols + 1, " MLT sensor setup"); - prompt(200, pmpt); - break; - case 5: snprintf(pmpt, Config.lcd_cols + 1, " MLT heater setup"); - prompt(200, pmpt); - break; - case 6: snprintf(pmpt, Config.lcd_cols + 1, " MLT pump setup"); - prompt(200, pmpt); - break; - case 7: snprintf(pmpt, Config.lcd_cols + 1, "MLT heat b4 HLT: %s", unit->hlt_heater_mltfirst ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 8: snprintf(pmpt, Config.lcd_cols + 1, "Pump cycle: %3d mins", unit->pump_cycle); - prompt(200, pmpt); - break; - case 9: snprintf(pmpt, Config.lcd_cols + 1, "Pump rest : %3d mins", unit->pump_rest); - prompt(200, pmpt); - break; - case 10: snprintf(pmpt, Config.lcd_cols + 1, " Pump pre-mash: %s", unit->pump_premash ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 11: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-mash: %s", unit->pump_onmash ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 12: snprintf(pmpt, Config.lcd_cols + 1, " Pump mashout: %s", unit->pump_mashout ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 13: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-boil: %s", unit->pump_onboil ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 14: snprintf(pmpt, Config.lcd_cols + 1, " Pump stop: %5.1f\001", unit->pump_stop); - prompt(200, pmpt); - break; - case 15: snprintf(pmpt, Config.lcd_cols + 1, " Skip Add: %s", unit->skip_add ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 16: snprintf(pmpt, Config.lcd_cols + 1, " Skip Remove: %s", unit->skip_remove ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 17: snprintf(pmpt, Config.lcd_cols + 1, " Skip Iodine: %s", unit->skip_iodine ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 18: snprintf(pmpt, Config.lcd_cols + 1, "Iodine time: %3d min", unit->iodine_time); - prompt(200, pmpt); - break; - case 19: snprintf(pmpt, Config.lcd_cols + 1, " Whirlpool: %s", unit->whirlpool ? (char *)"Yes":(char *)"No"); - prompt(200, pmpt); - break; - case 20: snprintf(pmpt, Config.lcd_cols + 1, " HLT PID setup"); - prompt(200, pmpt); - break; - case 21: snprintf(pmpt, Config.lcd_cols + 1, " MLT PID setup"); - prompt(200, pmpt); - break; - } - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) { - ncrc = crc32(ncrc, (const Bytef *)unit, sizeof(units_list)); - if (ocrc != ncrc) - wrconfig(); - if (debug) - fprintf(stdout, "End edit brewsystem %d %s\n", unit->number, unit->uuid); - return; - } - - if ((key == KEY_UP) && (idx > 1)) - idx--; - if ((key == KEY_DOWN) && (idx < 21)) - idx++; - - if (key == KEY_ENTER) { - switch(idx) { - case 1: name = calloc(sizeof(char), 21); - snprintf(name, 21, unit->name); - editName(name, (char *)"Unit name"); - if (unit->name) - free(unit->name); - unit->name = xstrcpy(name); - free(name); - break; - case 2: uuid = xstrcpy(unit->hlt_sensor.uuid); - editSensor(uuid, (char *)"HLT sensor"); - strncpy(unit->hlt_sensor.uuid, uuid, 36); - free(uuid); - break; - case 3: uuid = xstrcpy(unit->hlt_heater.uuid); - editRelay(uuid, (char *)"HLT heater"); - strncpy(unit->hlt_heater.uuid, uuid, 36); - free(uuid); - break; - case 4: uuid = xstrcpy(unit->mlt_sensor.uuid); - editSensor(uuid, (char *)"MLT sensor"); - strncpy(unit->mlt_sensor.uuid, uuid, 36); - free(uuid); - break; - case 5: uuid = xstrcpy(unit->mlt_heater.uuid); - editRelay(uuid, (char *)"MLT heater"); - strncpy(unit->mlt_heater.uuid, uuid, 36); - free(uuid); - break; - case 6: uuid = xstrcpy(unit->mlt_pump.uuid); - editRelay(uuid, (char *)"MLT pump"); - strncpy(unit->mlt_pump.uuid, uuid, 36); - free(uuid); - break; - case 7: toggleYesNo(&unit->hlt_heater_mltfirst, (char *)"MLT heat b4 HLT"); - break; - case 8: editInteger(&unit->pump_cycle, 5, 15, 1, (char *)"Pump cycle", (char *)"mins"); - break; - case 9: editInteger(&unit->pump_rest, 1, 5, 1, (char *)"Pump rest ", (char *)"mins"); - break; - case 10: toggleYesNo(&unit->pump_premash, (char *)" Pump pre-mash"); - break; - case 11: toggleYesNo(&unit->pump_onmash, (char *)" Pump on-mash"); - break; - case 12: toggleYesNo(&unit->pump_mashout, (char *)" Pump mashout"); - break; - case 13: toggleYesNo(&unit->pump_onboil, (char *)" Pump on-boil"); - break; - case 14: editFloat(&unit->pump_stop, 80.0, 110.0, (char *)" Pump stop"); - break; - case 15: toggleYesNo(&unit->skip_add, (char *)"Skip add water"); - break; - case 16: toggleYesNo(&unit->skip_remove, (char *)"Skip remove Mash"); - break; - case 17: toggleYesNo(&unit->skip_iodine, (char *)"Skip iodine test"); - break; - case 18: editInteger(&unit->iodine_time, 10, 240, 10, (char *)"Iodine time", (char *)"min"); - break; - case 19: toggleYesNo(&unit->whirlpool, (char *)"Do a whirlpool"); - break; - case 20: editPID(unit->PID_hlt); - break; - case 21: editPID(unit->PID_mlt); - break; - } - } - } -} - - - -void addUnit(int number) -{ - units_list *tmpu, *unit = (units_list *)malloc(sizeof(units_list)); - char name[81]; - uuid_t uu; - double Input, Output, Setpoint; - - if (debug) - fprintf(stdout, "Adding new brewsystem %d\n", number); - unit->next = NULL; - unit->version = 1; - unit->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, unit->uuid); - snprintf(name, 20, "System %d", number); - unit->name = xstrcpy(name); - unit->number = number; - if (number == 1) - unit->active = 1; - else - unit->active = 0; - unit->hlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->hlt_sensor.state = DEVPRESENT_UNDEF; - unit->hlt_sensor.value = 0; - unit->mlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_sensor.state = DEVPRESENT_UNDEF; - unit->mlt_sensor.value = 0; - unit->hlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->hlt_heater.value = 0; - unit->hlt_heater.delay = 0; - unit->mlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_heater.value = 0; - unit->mlt_heater.delay = 0; - unit->mlt_pump.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000"); - unit->mlt_pump.value = 0; - unit->mlt_pump.delay = 0; - unit->hlt_heater_mltfirst = 1; - unit->pump_cycle = 7; - unit->pump_rest = 2; - unit->pump_premash = 1; - unit->pump_onmash = 1; - unit->pump_mashout = 0; - unit->pump_onboil = 0; - unit->pump_stop = 90; - unit->skip_add = 0; - unit->skip_remove = 0; - unit->skip_iodine = 0; - unit->iodine_time = 90; - unit->whirlpool = 1; - unit->PID_hlt = (pid_var *)malloc(sizeof(pid_var)); - unit->PID_mlt = (pid_var *)malloc(sizeof(pid_var)); - Input = Setpoint = 20.0; - Output = 0; - PID_init(unit->PID_hlt, &Input, &Output, &Setpoint, 2, 5, 1, P_DIRECT); - PID_init(unit->PID_mlt, &Input, &Output, &Setpoint, 2, 5, 1, P_DIRECT); - - editUnit(unit); - - if (Config.units == NULL) { - Config.units = unit; - } else { - for (tmpu = Config.units; tmpu; tmpu = tmpu->next) { - if (tmpu->next == NULL) { - tmpu->next = unit; - break; - } - } - } - syslog(LOG_NOTICE, "Brewsystem %d added to the configuration", number); - if (debug) - fprintf(stdout, "Brewsystem %d added to the configuration\n", number); -} - - - -/* - * Edit a single recipe - */ -void editRecipe(a_recipe *recipe) -{ - int idx = 1, i, key; - char pmpt[81], *name; - uLong ocrc, ncrc; - - if (debug) - fprintf(stdout, "Start edit recipe `%s' %s\n", recipe->name, recipe->uuid); - - prompt(0, NULL); - ncrc = ocrc = crc32(0L, Z_NULL, 0); - ocrc = crc32(ocrc, (const Bytef *) recipe, sizeof(a_recipe)); - - for (;;) { - - prompt(0, NULL); - prompt(191, NULL); /* " Edit recipe " */ - - if (idx == 1) - prompt(402, NULL); /* "--- dwn quit ok " */ - else if (idx == 24) - prompt(404, NULL); /* " up --- quit ok " */ - else - prompt(403, NULL); /* " up dwn quit ok " */ - - switch (idx) { // 12345678901234567890 - case 1: snprintf(pmpt, Config.lcd_cols + 1, "Recipe name:"); - prompt(200, pmpt); - snprintf(pmpt, Config.lcd_cols + 1, "%s", recipe->name); - prompt(300, pmpt); - break; - case 2: snprintf(pmpt, Config.lcd_cols + 1, "Recipe code:"); - prompt(200, pmpt); - snprintf(pmpt, Config.lcd_cols + 1, "%s", recipe->code); - prompt(300, pmpt); - break; - case 3: snprintf(pmpt, Config.lcd_cols + 1, "Boil time: %3d mins", recipe->boiltime); - prompt(200, pmpt); - break; - case 4: snprintf(pmpt, Config.lcd_cols + 1, " Cool to: %5.1f\001", recipe->coolto); - prompt(200, pmpt); - break; - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: snprintf(pmpt, Config.lcd_cols + 1, "Mash: %s", recipe->mash[idx - 5].name); - prompt(200, pmpt); - if (recipe->mash[idx - 5].skip) - snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); - else - snprintf(pmpt, Config.lcd_cols + 1, " Sv %4.1f\001 %3d mins", recipe->mash[idx - 5].setpoint, recipe->mash[idx - 5].duration); - prompt(300, pmpt); - break; - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: snprintf(pmpt, Config.lcd_cols + 1, "Add: %s", recipe->hops[idx - 13].name); - prompt(200, pmpt); - if (recipe->hops[idx - 13].skip) - snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); - else { - if (recipe->hops[idx - 13].boiltime == -1) - snprintf(pmpt, Config.lcd_cols + 1, " First Wort Hop"); - else - snprintf(pmpt, Config.lcd_cols + 1, " Boil for %3d mins", recipe->hops[idx - 13].boiltime); - } - prompt(300, pmpt); - break; - case 23: - case 24: - case 25: snprintf(pmpt, Config.lcd_cols + 1, "Hopstand: %s", recipe->hopstand[idx - 23].name); - prompt(200, pmpt); - if (recipe->hopstand[idx - 23].skip) - snprintf(pmpt, Config.lcd_cols + 1, " Skipped"); - else if (recipe->hopstand[idx - 23].hold) - snprintf(pmpt, Config.lcd_cols + 1, "Hold at %4.1f %3d mins", recipe->hopstand[idx - 23].setpoint, recipe->hopstand[idx - 23].duration); - else - snprintf(pmpt, Config.lcd_cols + 1, "Hold for %3d mins", recipe->hopstand[idx - 23].duration); - prompt(300, pmpt); - break; - } - - key = keywait(); - if ((key == KEY_RETURN) || my_shutdown) { - ncrc = crc32(ncrc, (const Bytef *)recipe, sizeof(a_recipe)); - 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; - } - - if ((key == KEY_UP) && (idx > 1)) - idx--; - if ((key == KEY_DOWN) && (idx < 24)) - idx++; - - if (key == KEY_ENTER) { - switch(idx) { - case 1: name = calloc(sizeof(char), 21); - snprintf(name, 21, recipe->name); - editName(name, (char *)"Recipe name"); - if (recipe->name) - free(recipe->name); - recipe->name = xstrcpy(name); - free(name); - break; - case 2: name = calloc(sizeof(char), 21); - snprintf(name, 21, recipe->code); - editName(name, (char *)"Recipe code"); - if (recipe->code) - free(recipe->code); - recipe->code = xstrcpy(name); - free(name); - break; - case 3: editInteger(&recipe->boiltime, 60, 240, 5, (char *)"Boil time:", (char *)"mins"); - break; - case 4: editFloat(&recipe->coolto, 10.0, 30.0, (char *)" Cool to"); - - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: editMash(&recipe->mash[idx-5]); - break; - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: editHopaddition(&recipe->hops[idx-13], recipe->boiltime); - break; - case 23: - case 24: - case 25: editHopstand(&recipe->hopstand[idx-23]); - break; - } - } - } -} - - - -void addRecipe(int number) -{ - a_recipe *tmpu, *recipe = (a_recipe *)malloc(sizeof(a_recipe)); - char name[81]; - uuid_t uu; - - if (debug) - fprintf(stdout, "Adding new recipe %d\n", number); - recipe->next = NULL; - recipe->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, recipe->uuid); - snprintf(name, 21, "New recipe %d", number); - recipe->name = xstrcpy(name); - snprintf(name, 21, "%04d", number); - recipe->code = xstrcpy(name); - recipe->boiltime = 90; - recipe->coolto = 20.0; - recipe->starttime = recipe->endtime = (time_t)0; - /* - * Initial mash schedule, set a single-step 67 degr. mash - */ - recipe->mash[0].name = xstrcpy((char *)"Mash-in"); - recipe->mash[0].min = 20; - recipe->mash[0].max = 80; - recipe->mash[0].canskip = 0; - recipe->mash[0].setpoint = 68.0; - recipe->mash[0].skip = 0; - recipe->mash[0].duration = 1; - recipe->mash[1].name = xstrcpy((char *)"Phytase"); - recipe->mash[1].min = 25; - recipe->mash[1].max = 55; - recipe->mash[1].canskip = 1; - recipe->mash[1].setpoint = 40.0; - recipe->mash[1].skip = 1; - recipe->mash[1].duration = 10; - recipe->mash[2].name = xstrcpy((char *)"Glucanase"); - recipe->mash[2].min = 35; - recipe->mash[2].max = 50; - recipe->mash[2].canskip = 1; - recipe->mash[2].setpoint = 45.0; - recipe->mash[2].skip = 1; - recipe->mash[2].duration = 10; - recipe->mash[3].name = xstrcpy((char *)"Protease"); - recipe->mash[3].min = 45; - recipe->mash[3].max = 60; - recipe->mash[3].canskip = 1; - recipe->mash[3].setpoint = 55.0; - recipe->mash[3].skip = 1; - recipe->mash[3].duration = 10; - recipe->mash[4].name = xstrcpy((char *)"B-Amylase"); - recipe->mash[4].min = 50; - recipe->mash[4].max = 70; - recipe->mash[4].canskip = 1; - recipe->mash[4].setpoint = 62.0; - recipe->mash[4].skip = 1; - recipe->mash[4].duration = 30; - recipe->mash[5].name = xstrcpy((char *)"A-Amylase 1"); - recipe->mash[5].min = 60; - recipe->mash[5].max = 76; - recipe->mash[5].canskip = 1; - recipe->mash[5].setpoint = 67.0; - recipe->mash[5].skip = 1; - recipe->mash[5].duration = 30; - recipe->mash[6].name = xstrcpy((char *)"A-Amylase 2"); - recipe->mash[6].min = 60; - recipe->mash[6].max = 76; - recipe->mash[6].canskip = 0; - recipe->mash[6].setpoint = 67.0; - recipe->mash[6].skip = 0; - recipe->mash[6].duration = 60; - recipe->mash[7].name = xstrcpy((char *)"Mash-out"); - recipe->mash[7].min = 75; - recipe->mash[7].max = 80; - recipe->mash[7].canskip = 0; - recipe->mash[7].setpoint = 78.0; - recipe->mash[7].skip = 0; - recipe->mash[7].duration = 10; - - /* - * 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; - 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. - */ - recipe->hopstand[0].name = xstrcpy((char *)"Hopstand hot"); - recipe->hopstand[0].min = 88; - recipe->hopstand[0].max = 100; - recipe->hopstand[0].hold = 0; - recipe->hopstand[0].setpoint = 93.0; - recipe->hopstand[0].skip = 1; - recipe->hopstand[0].duration = 30; - recipe->hopstand[1].name = xstrcpy((char *)"Hopstand default"); - recipe->hopstand[1].min = 72; - recipe->hopstand[1].max = 77; - recipe->hopstand[1].hold = 0; - recipe->hopstand[1].setpoint = 75.0; - recipe->hopstand[1].skip = 1; - recipe->hopstand[1].duration = 60; - recipe->hopstand[2].name = xstrcpy((char *)"Hopstand cool"); - recipe->hopstand[2].min = 60; - recipe->hopstand[2].max = 66; - recipe->hopstand[2].hold = 0; - recipe->hopstand[2].setpoint = 63.0; - recipe->hopstand[2].skip = 1; - recipe->hopstand[2].duration = 60; - - editRecipe(recipe); - - if (recipes == NULL) { - recipes = recipe; - } else { - for (tmpu = recipes; tmpu; tmpu = tmpu->next) { - if (tmpu->next == NULL) { - tmpu->next = recipe; - break; - } - } - } - syslog(LOG_NOTICE, "Recipe %d added", number); - if (debug) - fprintf(stdout, "Recipe %d added\n", number); -} - - - -void editRecipes(void) -{ - int total, i, key, choice = 1;; - a_recipe *recipe; - char pmpt[81]; - - prompt(0, NULL); - for (;;) { - total = 0; - for (recipe = recipes; recipe; recipe = recipe->next) { - total++; - } - - if (debug) - fprintf(stdout, "editRecipes total=%d choice=%d\n", total, choice); - - i = 0; - if (total) { - 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 == 0) - prompt(416, NULL); /* "add --- quit --- " */ - else if (total == 1) - prompt(415, NULL); /* "add --- quit ok " */ - else if (total && (choice == 1)) - prompt(414, NULL); /* "add dwn quit ok " */ - else if (total && (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; - if (total && (key == KEY_ENTER)) { - editRecipe(recipe); - prompt(0, NULL); - } - if (key == KEY_UP) { - if ((total == 1) || (choice == 1)) - addRecipe(total + 1); - else if (choice > 1) - choice--; - } - if ((key == KEY_DOWN) && (total > 1) && (choice < total)) - choice++; - } -} - - - -void editUnits(void) -{ - int total, i, key, choice = 1;; - units_list *unit; - char pmpt[81]; - - prompt(0, NULL); - for (;;) { - total = 0; - for (unit = Config.units; unit; unit = unit->next) { - total++; - } - - if (debug) - fprintf(stdout, "editUnits total=%d choice=%d\n", total, choice); - - if (total == 0) { - /* - * Impossible unless first setup was skipped - */ - addUnit(1); - total = 1; - } else { - i = 0; - for (unit = Config.units; unit; unit = unit->next) { - i++; - if (i == choice) - break; - } - prompt(102, NULL); /* " SETUP MENU " */ - prompt(222, NULL); /* " Select Brewsystem " */ - snprintf(pmpt, Config.lcd_cols + 1, "%s ", unit->name); - prompt(300, pmpt); - if (total == 1) - prompt(415, NULL); /* "add --- quit ok " */ - else if (choice == 1) - prompt(414, NULL); /* "add 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; - if (key == KEY_ENTER) { - editUnit(unit); - prompt(0, NULL); - } - if (key == KEY_UP) { - if ((total == 1) || (choice == 1)) - addUnit(total + 1); - else if (choice > 1) - choice--; - } - if ((key == KEY_DOWN) && (total > 1) && (choice < total)) - choice++; - } - } -} - - - -void setup(void) -{ - int key, option = 202; - - for (;;) { - if (debug) - fprintf(stdout, "setup() option=%d\n", option); - prompt(0, NULL); - prompt(102, NULL); /* " SETUP MENU " */ - prompt(option, NULL); - if (option == 202) - prompt(402, NULL); /* "--- dwn quit ok " */ -#ifdef USE_SIMULATOR - else if (option == 205) -#else - else if (option == 204) -#endif - 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) && (option > 202)) { - option--; - } -#ifdef USE_SIMULATOR - if ((key == KEY_DOWN) && (option < 205)) { -#else - if ((key == KEY_DOWN) && (option < 204)) { -#endif - option++; - } - - if (key == KEY_ENTER) { - switch(option) { - case 202: editRecipes(); - break; - case 203: editUnits(); - break; - case 204: // devices - break; -#ifdef USE_SIMULATOR - case 205: // simulator - break; -#endif - } - if (my_shutdown) - return; - } - } -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/setup.h --- a/brewco/setup.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#ifndef _SETUP_H -#define _SETUP_H - - -void editInteger(int *, int, int, int, char *, char *); -void editUnit(units_list *); -void addUnit(int); -void setup(void); - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/simulator.c --- a/brewco/simulator.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +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 "simulator.h" - -#ifdef USE_SIMULATOR - -extern int my_shutdown; -extern int debug; -extern sys_config Config; - -int SIM_hlt_value = 0; -int SIM_mlt_value = 0; -int SIM_cooler = FALSE; - - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_simulator_loop) -#else -void *my_simulator_loop(void *threadid) -#endif -{ - time_t now, last; - int loops = 0; -// double hlt_heat_transfer, mlt_heat_transfer; -// double vhc_air = 0.00121, vhc_water = 4.1796; - - syslog(LOG_NOTICE, "Thread my_simulator_loop started"); - if (debug) - fprintf(stdout, "Thread my_simulator_loop started\n"); - - /* - * Initial temperatures - */ - Config.simulator->hlt_heater_temp = Config.simulator->hlt_temperature; - Config.simulator->mlt_heater_temp = Config.simulator->mlt_temperature; - last = now = time(NULL); - - /* - * About 50 mSec loops - */ - for (;;) { - if (my_shutdown) - break; - - /* - * First calculate the heat loss for the HLT and MLT liquids. - * Then decrease both liquid temperatures and consider the volume. - */ - Config.simulator->hlt_temperature -= (Config.simulator->hlt_temperature - Config.simulator->room_temperature) / - (80000 * (Config.simulator->hlt_heater_volume / 2)); - Config.simulator->mlt_temperature -= (Config.simulator->mlt_temperature - Config.simulator->room_temperature) / - (80000 * (Config.simulator->mlt_heater_volume / 2)); - - /* - * If heating, calculate the heating element temperature but not higher then 250 degrees celcius. - * I have no data about real temperatures of electric elements, so this is a rough guess. - * If not heating, the elements are couling towards the current liquid temperature. - */ - Config.simulator->hlt_heater_state = SIM_hlt_value; - if (SIM_hlt_value) { - Config.simulator->hlt_heater_temp += (250 - Config.simulator->hlt_heater_temp) / 2000.0 * (Config.simulator->hlt_heater_power / 2000.0); - } else { - Config.simulator->hlt_heater_temp -= (Config.simulator->hlt_heater_temp - Config.simulator->hlt_temperature) / 250; - } - Config.simulator->mlt_heater_state = SIM_mlt_value; - if (SIM_mlt_value) { - Config.simulator->mlt_heater_temp += (250 - Config.simulator->mlt_heater_temp) / 2000.0 * (Config.simulator->mlt_heater_power / 2000.0); - } else { - Config.simulator->mlt_heater_temp -= (Config.simulator->mlt_heater_temp - Config.simulator->mlt_temperature) / 250; - } - - /* - * If cooling, bring down the MLT temperature. Assume 14 degrees coolwater. - * The cooler is turned on or off by sending SIGUSR1 or SIGUSR2 to this program. - */ - if (SIM_cooler) { - Config.simulator->mlt_temperature -= (Config.simulator->mlt_temperature - 14) / (175 * Config.simulator->hlt_heater_volume); - } - - /* - * Shift the liquid temperature towards the heating elements temperature, - * but never higher then 100 degrees celcius. - */ - Config.simulator->hlt_temperature += (Config.simulator->hlt_heater_temp - Config.simulator->hlt_temperature) / - (10000.0 * Config.simulator->hlt_heater_volume * (2000.0 / Config.simulator->hlt_heater_power)); - if (Config.simulator->hlt_temperature > 100.25) - Config.simulator->hlt_temperature = 100.25; - Config.simulator->mlt_temperature += (Config.simulator->mlt_heater_temp - Config.simulator->mlt_temperature) / - (10000.0 * Config.simulator->mlt_heater_volume * (2000.0 / Config.simulator->mlt_heater_power)); - if (Config.simulator->mlt_temperature > 100.25) - Config.simulator->mlt_temperature = 100.25; - - loops++; - now = time(NULL); - if (now != last) { - last = now; - /* - * Each second - */ -// if (debug) -// fprintf(stdout, "HLT temp=%f plate=%f val=%d MLT temp=%f plate=%f val=%d Room %.1f loops=%d cool=%s\n", -// Config.simulator->hlt_temperature, Config.simulator->hlt_heater_temp, Config.simulator->hlt_heater_state, -// Config.simulator->mlt_temperature, Config.simulator->mlt_heater_temp, Config.simulator->mlt_heater_state, -// Config.simulator->room_temperature, loops, SIM_cooler ? "Yes":"No"); - loops = 0; - } - usleep(50000); - } - - syslog(LOG_NOTICE, "Thread my_simulator_loop stopped"); - if (debug) - fprintf(stdout, "Thread my_simulator_loop stopped\n"); - return 0; -} - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/simulator.h --- a/brewco/simulator.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#ifndef SIMULATOR_H -#define SIMULATOR_H - -#ifdef USE_SIMULATOR - - -#ifdef HAVE_WIRINGPI_H -PI_THREAD (my_simulator_loop); -#else -void *my_simulator_loop(void *); -#endif - -#endif - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/slcd.c --- a/brewco/slcd.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +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 "slcd.h" -#include "util.h" -#include "xutil.h" - - - -struct sockaddr_in sendaddr; /* Server send socket */ -int sock = -1; -uint16_t keys = 0x0000; -uint16_t leds = 0x0400; /* LED's, buzzer, LCD backlight */ -uint16_t oleds = 0x0400; - -extern int debug; -extern sys_config Config; - - - -void putLCDsocket(int fd, uint16_t data) -{ - socklen_t slen; - uint16_t rdat; - - if (sock == -1) - return; - - if (sendto(sock, &data, sizeof(uint16_t), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr)) != sizeof(uint16_t)) { - syslog(LOG_NOTICE, "Socket %d send failed, closing socket: %s", sock, strerror(errno)); - if (shutdown(sock, SHUT_RDWR)) { - syslog(LOG_NOTICE, "Can't shutdown socket: %s", strerror(errno)); - } - sock = -1; - } else { - if (recvfrom(sock, &rdat, sizeof(uint16_t), 0, (struct sockaddr *) &sendaddr, &slen) != sizeof(uint16_t)) { - syslog(LOG_NOTICE, "Socket %d recvfrom failed, closing socket: %s", sock, strerror(errno)); - if (shutdown(sock, SHUT_RDWR)) { - syslog(LOG_NOTICE, "Can't shutdown socket: %s", strerror(errno)); - } - sock = -1; - } else { - if ((rdat & SLCD_MKEYS) == SLCD_KEYS) { - if (((rdat & 0x00ff) != keys) && debug) - fprintf(stdout, "received keys %04x was %04x\n", rdat & 0x00ff, keys); - keys = rdat & 0x00ff; - } else { - if (debug) - fprintf(stdout, "received %04x\n", rdat); - } - - } - } -} - - - -void slcdDummy(int fd) -{ - putLCDsocket(fd, SLCD_NULL); -} - - - -void slcdLEDs(int fd) -{ - if (leds != oleds) - putLCDsocket(fd, leds); - oleds = leds; -} - - -//void slcdHome(int fd) -//{ -//} - - - -void slcdClear(int fd) -{ - putLCDsocket(fd, SLCD_CLEAR); - putLCDsocket(fd, SLCD_HOME); -} - - - -//void slcdDisplay(int fd, int state) -//{ -//} - - - -//void slcdCursor(int fd, int state) -//{ -//} - - - -//void slcdCursorBlink(int fd, int state) -//{ -//} - - - -//void slcdSendCommand(int fd, unsigned char command) -//{ -//} - - - -void slcdPosition(int fd, int x, int y) -{ - uint16_t data = SLCD_DGRAM; - - data += (x & 0x1f) + ((y & 0x03) << 5); - putLCDsocket(fd, data); -} - - - -void slcdCharDef(int fd, int idx, unsigned char data[8]) -{ - int i; - uint16_t byte; - - if (debug) - fprintf(stdout, "CharDef(%d, %d, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x)\n", fd, idx, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - - byte = SLCD_CGRAM | ((idx & 7) << 3); - putLCDsocket(fd, byte); - for (i = 0; i < 8; i++) { - byte = data[i] & 0xff; - putLCDsocket(fd, byte); - } -} - - - -void slcdPutchar(int fd, unsigned char c) -{ - uint16_t data = SLCD_DATA; - - data += c & 0x0ff; - putLCDsocket(fd, data); -} - - - -void slcdPuts(int fd, const char *string) -{ - while (*string) - slcdPutchar(fd, *string++); -} - - - -void slcdPrintf(int fd, const char *message, ...) -{ - char buf[81 * sizeof(char)]; - va_list va_ptr; - - va_start(va_ptr, message); - vsnprintf(buf, (Config.lcd_cols + 1) * sizeof(char), message, va_ptr); - va_end(va_ptr); - slcdPuts(fd, buf); -} - - - -/* - * Try to setup a udp connection to 127.0.0.1 so we duplicate the panel - * display and keys of the real panel. This should fail on a production - * system because there should no brewpanel program be running. If it - * succeeds, all io will be duplicated over the network. - */ -int slcdInit(int fd, int cols, int rows) -{ - if ((sock = socket(AF_INET, SOCK_DGRAM /*| SOCK_NONBLOCK */, 0)) < 0) { - syslog(LOG_NOTICE, "slcdInit() can't create socket: %s", strerror(errno)); - return -1; - } - - /* - * Setup address structure for the server socket. - */ - memset(&sendaddr, 0, sizeof(struct sockaddr_in)); - sendaddr.sin_family = AF_INET; - sendaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - sendaddr.sin_port = htons(SEND_PORT); - - if (connect(sock, (struct sockaddr *)&sendaddr, sizeof(sendaddr)) < 0) { - close(sock); - sock = -1; - syslog(LOG_NOTICE, "slcdInit() can't bind sendsock %s", strerror(errno)); - return -1; - } - - syslog(LOG_NOTICE, "slcdInit() socket %d to brewpanel is active", sock); - return 0; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/slcd.h --- a/brewco/slcd.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#ifndef _SLCD_H -#define _SLCD_H - - -void slcdDummy(int fd); -void slcdLEDs(int fd); -void slcdClear(int fd); -void slcdPosition(int fd, int x, int y); -void slcdCharDef(int fd, int index, unsigned char data[8]); -void slcdPutchar(int fd, unsigned char c); -void slcdPuts(int fd, const char *string); -void slcdPrintf(int fd, const char *message, ...); -int slcdInit(int fd, int cols, int rows); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/util.c --- a/brewco/util.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +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 "util.h" -#include "slcd.h" - -#ifdef HAVE_WIRINGPI_H -extern int lcdHandle; -#endif -extern int slcdHandle; - - -/* - * Make directory tree, the name must end with a / - */ -int mkdirs(char *name, mode_t mode) -{ - char buf[PATH_MAX], *p, *q; - int last = 0, oldmask; - - memset(&buf, 0, sizeof(buf)); - strncpy(buf, name, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - - p = buf+1; - - oldmask = umask(000); - while ((q = strchr(p, '/'))) { - *q = '\0'; - mkdir(buf, mode); - last = errno; - *q = '/'; - p = q+1; - } - - umask(oldmask); - - if ((last == 0) || (last == EEXIST)) { - return TRUE; - } else { - syslog(LOG_NOTICE, "mkdirs(%s)", name); - return FALSE; - } -} - - - -/* - * Test if the given file exists. The second option is: - * R_OK - test for Read rights - * W_OK - test for Write rights - * X_OK - test for eXecute rights - * F_OK - test file presence only - */ -int file_exist(char *path, int mode) -{ - if (access(path, mode) != 0) - return errno; - - return 0; -} - - - -/* - * Buffered filecopy, filetime is preserved. - */ -int file_cp(char *from, char *to) -{ - char *line; - FILE *stfrom, *stto; - int dummy, bread; - static int error; - struct stat sb; - struct utimbuf ut; - - stfrom = fopen(from, "r"); - if (stfrom == NULL) - return errno; - - stto = fopen(to, "w"); - if (stto == NULL) { - error = errno; - fclose(stfrom); - return error; - } - - line = malloc(16384); - do { - bread = fread(line, 1, 16384, stfrom); - dummy = fwrite(line, 1, bread, stto); - if (bread != dummy) { - error = errno; - fclose(stfrom); - fclose(stto); - unlink(to); - free(line); - return error; - } - } while (bread != 0); - free(line); - fclose(stfrom); - if (fclose(stto) != 0) { - error = errno; - unlink(to); - return error; - } - - /* - * copy successfull, now copy file- and modification-time - */ - if (stat(from, &sb) == 0) { - ut.actime = mktime(localtime(&sb.st_atime)); - ut.modtime = mktime(localtime(&sb.st_mtime)); - if (utime(to, &ut) != 0) { - error = errno; - unlink(to); - return error; - } - chmod(to, sb.st_mode); - } - - return 0; -} - - -#ifndef HAVE_WIRINGPI_H -long millis(void) -{ - struct timespec now; - - clock_gettime(CLOCK_REALTIME , &now); - return ((now.tv_sec * 1000000000) + now.tv_nsec) / 1000000; -} -#endif - - -void hlt_status(int value) -{ -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 0, 1); -#endif - slcdPosition(slcdHandle, 0, 1); - if (value) { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 5); -#endif - slcdPutchar(slcdHandle, 5); - } else { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 6); -#endif - slcdPutchar(slcdHandle, 6); - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_LCD); -#endif -} - - - -void mlt_status(int value) -{ -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 18, 1); -#endif - slcdPosition(slcdHandle, 18, 1); - if (value) { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 5); -#endif - slcdPutchar(slcdHandle, 5); - } else { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 6); -#endif - slcdPutchar(slcdHandle, 6); - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_LCD); -#endif -} - - - -void pump_status(int value) -{ -#ifdef HAVE_WIRINGPI_H - piLock(LOCK_LCD); - lcdPosition(lcdHandle, 19, 1); -#endif - slcdPosition(slcdHandle, 19, 1); - if (value) { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 3); -#endif - slcdPutchar(slcdHandle, 3); - } else { -#ifdef HAVE_WIRINGPI_H - lcdPutchar(lcdHandle, 4); -#endif - slcdPutchar(slcdHandle, 4); - } -#ifdef HAVE_WIRINGPI_H - piUnlock(LOCK_LCD); -#endif -} - - - -/* From ArdBir */ -float Arrotonda025(float Num){ - // Appoggio la parte intera - int Appoggio= (int)Num; - - // Arrotondo il valore con peso 0.25 - return Appoggio+(int)((Num-Appoggio)*1000/225)*0.25; -} - -float ConvertiCtoF(float Num){ - Num = Num/16; // Recupero il valore - Num = (Num*1.8)+32; // Converto in °F - Num = Arrotonda025(Num); - return Num*16; // Preparo il valore per la registrazione -} -float ConvertiFtoC(float Num){ - Num = Num/16; // Recupero il valore - Num = (Num-32)/1.8; // Converto in °C - Num = Arrotonda025(Num); - return Num*16; // Preparo il valore per la registrazione -} - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/util.h --- a/brewco/util.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#ifndef _UTIL_H -#define _UTIL_H - - -int mkdirs(char *, mode_t); -int file_exist(char *, int); -int file_cp(char *, char *); -#ifndef HAVE_WIRINGPI_H -long millis(void); -#endif -void hlt_status(int); -void mlt_status(int); -void pump_status(int); - - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 brewco/xutil.c --- a/brewco/xutil.c Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +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 "xutil.h" - - -char *xmalloc(size_t size) -{ - char *tmp; - - tmp = malloc(size); - if (!tmp) - abort(); - - return tmp; -} - - - -char *xstrcpy(char *src) -{ - char *tmp; - - if (src == NULL) - return(NULL); - tmp = xmalloc(strlen(src)+1); - strcpy(tmp, src); - return tmp; -} - - - -char *xstrcat(char *src, char *add) -{ - char *tmp; - size_t size = 0; - - if ((add == NULL) || (strlen(add) == 0)) - return src; - if (src) - size = strlen(src); - size += strlen(add); - tmp = xmalloc(size + 1); - *tmp = '\0'; - if (src) { - strcpy(tmp, src); - free(src); - } - strcat(tmp, add); - return tmp; -} - - diff -r 5a237a99a793 -r d5bc44183aa4 brewco/xutil.h --- a/brewco/xutil.h Thu Feb 25 22:42:54 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef XUTIL_H -#define XUTIL_H - -char *xmalloc(size_t); -char *xstrcpy(char *); -char *xstrcat(char *, char *); - -#endif diff -r 5a237a99a793 -r d5bc44183aa4 configure --- a/configure Thu Feb 25 22:42:54 2016 +0100 +++ b/configure Thu Feb 25 23:14:46 2016 +0100 @@ -2031,13 +2031,13 @@ ac_config_headers="$ac_config_headers config.h" -SUBDIRS="dht11 rc433 thermferm brewco brewpanel" +SUBDIRS="dht11 rc433 thermferm brewpanel" PACKAGE="mbsePi-apps" -VERSION="0.5.1" -COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved" -CYEARS="2014-2015" +VERSION="0.5.2" +COPYRIGHT="Copyright (C) 2014-2016 Michiel Broek, All Rights Reserved" +CYEARS="2014-2016" diff -r 5a237a99a793 -r d5bc44183aa4 configure.ac --- a/configure.ac Thu Feb 25 22:42:54 2016 +0100 +++ b/configure.ac Thu Feb 25 23:14:46 2016 +0100 @@ -2,15 +2,15 @@ AC_INIT(thermferm/thermferm.c) AM_CONFIG_HEADER(config.h) -SUBDIRS="dht11 rc433 thermferm brewco brewpanel" +SUBDIRS="dht11 rc433 thermferm brewpanel" AC_SUBST(SUBDIRS) dnl General settings dnl After changeing the version number, run autoconf! PACKAGE="mbsePi-apps" -VERSION="0.5.1" -COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved" -CYEARS="2014-2015" +VERSION="0.5.2" +COPYRIGHT="Copyright (C) 2014-2016 Michiel Broek, All Rights Reserved" +CYEARS="2014-2016" AC_SUBST(PACKAGE) AC_SUBST(VERSION) AC_SUBST(COPYRIGHT)