Bumped to version 0.5.2 and removed the brewco subdirectory because that has been implemented as Arduino project.

Thu, 25 Feb 2016 23:14:46 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 25 Feb 2016 23:14:46 +0100
changeset 487
d5bc44183aa4
parent 486
5a237a99a793
child 488
bee1f70fb42b

Bumped to version 0.5.2 and removed the brewco subdirectory because that has been implemented as Arduino project.

brewco/Makefile file | annotate | diff | comparison | revisions
brewco/README file | annotate | diff | comparison | revisions
brewco/brewco.c file | annotate | diff | comparison | revisions
brewco/brewco.h file | annotate | diff | comparison | revisions
brewco/devices.c file | annotate | diff | comparison | revisions
brewco/devices.h file | annotate | diff | comparison | revisions
brewco/keyboard.c file | annotate | diff | comparison | revisions
brewco/keyboard.h file | annotate | diff | comparison | revisions
brewco/lcd-pcf8574.c file | annotate | diff | comparison | revisions
brewco/lcd-pcf8574.h file | annotate | diff | comparison | revisions
brewco/lock.c file | annotate | diff | comparison | revisions
brewco/lock.h file | annotate | diff | comparison | revisions
brewco/logger.c file | annotate | diff | comparison | revisions
brewco/logger.h file | annotate | diff | comparison | revisions
brewco/pid.c file | annotate | diff | comparison | revisions
brewco/pid.h file | annotate | diff | comparison | revisions
brewco/prompt.c file | annotate | diff | comparison | revisions
brewco/prompt.h file | annotate | diff | comparison | revisions
brewco/rdconfig.c file | annotate | diff | comparison | revisions
brewco/rdconfig.h file | annotate | diff | comparison | revisions
brewco/rdrecipes.c file | annotate | diff | comparison | revisions
brewco/rdrecipes.h file | annotate | diff | comparison | revisions
brewco/rdsession.c file | annotate | diff | comparison | revisions
brewco/rdsession.h file | annotate | diff | comparison | revisions
brewco/setup.c file | annotate | diff | comparison | revisions
brewco/setup.h file | annotate | diff | comparison | revisions
brewco/simulator.c file | annotate | diff | comparison | revisions
brewco/simulator.h file | annotate | diff | comparison | revisions
brewco/slcd.c file | annotate | diff | comparison | revisions
brewco/slcd.h file | annotate | diff | comparison | revisions
brewco/util.c file | annotate | diff | comparison | revisions
brewco/util.h file | annotate | diff | comparison | revisions
brewco/xutil.c file | annotate | diff | comparison | revisions
brewco/xutil.h file | annotate | diff | comparison | revisions
configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
--- 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
--- 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
-
---------------------
-
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
--- 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 <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <getopt.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <poll.h>
-#include <dirent.h>
-#include <uuid/uuid.h>
-#include <math.h>
-#include <zlib.h>
-
-
-#ifndef HAVE_WIRINGPI_H
-#include <pthread.h>
-#endif
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/encoding.h>
-#include <libxml/xmlwriter.h>
-
-#ifdef HAVE_WIRINGPI_H
-/* wiringPi */
-#include <wiringPi.h>
-#include <pcf8574.h>
-#include <lcd.h>
-
-/*
- * 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
--- 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
--- 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 <http://www.gnu.org/licenses/>.
- ***********************************************************************
- */
-
-#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 ;
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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);
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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 <br3ttb@gmail.com>
- * 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;
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-	}
-    }
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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
-}
-
--- 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
--- 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 <mbroek at mbse dot eu>
- *
- * 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;
-}
-
-
--- 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
--- 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"
 
 
 
--- 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)

mercurial