brewco/rdconfig.c

changeset 434
eb724767860d
parent 409
cdf68044adaf
child 435
4b1ed6897d80
--- a/brewco/rdconfig.c	Wed Nov 25 16:39:25 2015 +0100
+++ b/brewco/rdconfig.c	Wed Nov 25 22:49:35 2015 +0100
@@ -25,37 +25,84 @@
 #include "futil.h"
 #include "xutil.h"
 
-int		debug = FALSE;
+int		debug = TRUE;
 sys_config	Config;			/* System configuration		*/
 
 #define MY_ENCODING "utf-8"
 
 const char	TEMPSTATE[3][8] = { "OK", "MISSING", "ERROR" };
-//const char	DEVTYPE[8][6] = { "NA", "W1", "GPIO", "RC433", "DHT", "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	PIDMODE[3][5] = { "NONE", "AUTO", "BOO" };
+const char	DEVTYPE[8][6] = { "NA", "W1", "GPIO", "RC433", "DHT", "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	PIDMODE[3][5] = { "NONE", "AUTO", "BOO" };
 
 
 void killconfig(void)
 {
+    units_list          *unit;
+    devices_list        *device;
+#ifdef USE_SIMULATOR
+    simulator_list      *simulator;
+#endif
 
     if (Config.name)
 	free(Config.name);
     Config.name = NULL;
 
+    Config.my_port = 6554;
     Config.tempFormat = 'C';
-    if (Config.hlt_sensor_address)
-	free(Config.hlt_sensor_address);
-    if (Config.mlt_sensor_address)
-	free(Config.mlt_sensor_address);
-    Config.hlt_sensor_address = Config.mlt_sensor_address = NULL;
-    Config.hlt_sensor_value = Config.mlt_sensor_value = 20000;
-    Config.hlt_sensor_state = Config.mlt_sensor_state = 1;	// missing
+    if (Config.temp_address)
+        free(Config.temp_address);
+    if (Config.hum_address)
+        free(Config.hum_address);
+    Config.temp_address = Config.hum_address = NULL;
+    Config.temp_value = 20000;
+    Config.temp_state = Config.hum_state = 1;   // missing
+    Config.hum_value = 50000;
+    Config.lcd_cols = 20;
+    Config.lcd_rows = 4;
 
-#ifdef HAVE_WIRINGPI_H
-    Config.lcd_cols = 16;
-    Config.lcd_rows = 2;
+    for (unit = Config.units; unit; unit = unit->next) {
+        if (unit->uuid)
+            free(unit->uuid);
+        if (unit->name)
+            free(unit->name);
+        if (unit->hlt_sensor_address)
+            free(unit->hlt_sensor_address);
+        if (unit->mlt_sensor_address)
+            free(unit->mlt_sensor_address);
+        if (unit->hlt_heater_address)
+            free(unit->hlt_heater_address);
+        if (unit->mlt_heater_address)
+            free(unit->mlt_heater_address);
+        if (unit->mlt_pump_address)
+            free(unit->mlt_pump_address);
+        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
+    for (simulator = Config.simulators; simulator; simulator = simulator->next) {
+        if (simulator->uuid)
+            free(simulator->uuid);
+        if (simulator->name)
+            free(simulator->name);
+        free(simulator);
+    }
+    Config.simulators = NULL;
 #endif
 }
 
@@ -69,6 +116,11 @@
     char		*mypath = NULL;
     xmlTextWriterPtr	writer;
     xmlBufferPtr	buf;
+    units_list		*unit;
+    devices_list	*device;
+#ifdef USE_SIMULATOR
+    simulator_list      *simulator;
+#endif
 
     /* 
      * Create a new XML buffer, to which the XML document will be written
@@ -124,36 +176,39 @@
 	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 ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_ADDRESS", "%s", Config.hlt_sensor_address)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_ADDRESS", "%s", Config.temp_address)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;
     }
-    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_STATE", "%d", Config.hlt_sensor_state)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;                           
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_STATE", "%d", Config.temp_state)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;                           
     }
-    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_VALUE", "%d", Config.hlt_sensor_value)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_VALUE", "%d", Config.temp_value)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;
     }
-    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_ADDRESS", "%s", Config.mlt_sensor_address)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_ADDRESS", "%s", Config.hum_address)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;
     }   
-    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_STATE", "%d", Config.mlt_sensor_state)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;    
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_STATE", "%d", Config.hum_state)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;    
     }   
-    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_VALUE", "%d", Config.mlt_sensor_value)) < 0) {
-	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
-	return 1;
+    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_VALUE", "%d", Config.hum_value)) < 0) {
+        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+        return 1;
     }
 
-#ifdef HAVE_WIRINGPI_H
     /* 
      * Start an element named "LCDS" as child of BREWCO.
      */
@@ -199,6 +254,343 @@
 	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 (unit->hlt_sensor_address) {
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_ADDRESS", "%s", unit->hlt_sensor_address)) < 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 (unit->hlt_heater_address) {
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_ADDRESS", "%s", unit->hlt_heater_address)) < 0)) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_STATE", "%d", unit->hlt_heater_state)) < 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 (unit->mlt_sensor_address) {
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_ADDRESS", "%s", unit->mlt_sensor_address)) < 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 (unit->mlt_heater_address) {
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_ADDRESS", "%s", unit->mlt_heater_address)) < 0)) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_STATE", "%d", unit->mlt_heater_state)) < 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 (unit->mlt_pump_address) {
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_ADDRESS", "%s", unit->mlt_pump_address)) < 0)) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_STATE", "%d", unit->mlt_pump_state)) < 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 (unit->PID_hlt) {
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_IMAX", "%.2f", unit->PID_hlt->iMax)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_IGAIN", "%.2f", unit->PID_hlt->iGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_PGAIN", "%.2f", unit->PID_hlt->pGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_DGAIN", "%.2f", unit->PID_hlt->dGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_INPUT", "%.2f", unit->PID_hlt->Input)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_ERR", "%.2f", unit->PID_hlt->Err)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_ERRLAST", "%.2f", unit->PID_hlt->ErrLast)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_ISTATE", "%.2f", unit->PID_hlt->iState)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_SETP", "%.2f", unit->PID_hlt->SetP)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_OUTP", "%.2f", unit->PID_hlt->OutP)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_MODE", "%s", PIDMODE[unit->PID_hlt->Mode])) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_TYPE", "HEAT")) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+            }
+
+            if (unit->PID_mlt) {
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_IMAX", "%.2f", unit->PID_mlt->iMax)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_IGAIN", "%.2f", unit->PID_mlt->iGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_PGAIN", "%.2f", unit->PID_mlt->pGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_DGAIN", "%.2f", unit->PID_mlt->dGain)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_INPUT", "%.2f", unit->PID_mlt->Input)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_ERR", "%.2f", unit->PID_mlt->Err)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_ERRLAST", "%.2f", unit->PID_mlt->ErrLast)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_ISTATE", "%.2f", unit->PID_mlt->iState)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_SETP", "%.2f", unit->PID_mlt->SetP)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_OUTP", "%.2f", unit->PID_mlt->OutP)) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_MODE", "%s", PIDMODE[unit->PID_mlt->Mode])) < 0) {
+                    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                    return 1;
+                }
+                if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_TYPE", "HEAT")) < 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.simulators) {
+        if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "SIMULATORS")) < 0) {
+            syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+            return 1;
+        }
+        for (simulator = Config.simulators; simulator; simulator = simulator->next) {
+            if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "SIMULATOR")) < 0) {
+                syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+                return 1;
+            }
+            if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VERSION", "%d", simulator->version)) < 0) {
+                syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+                return 1;
+            }
+            if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", simulator->uuid)) < 0) {
+                syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+                return 1;
+            }
+            if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", simulator->name)) < 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;
+        }
+    }
 #endif
 
     /*
@@ -255,7 +647,6 @@
 /*
  * Parse one LCD display
  */
-#ifdef HAVE_WIRINGPI_H
 int parseLCD(xmlDocPtr doc, xmlNodePtr cur)
 {
     xmlChar	*key;
@@ -300,13 +691,569 @@
     }
     return 0;
 }
+
+
+
+/*
+ * Parse a brewsystem
+ */
+int parseBrewsystem(xmlDocPtr doc, xmlNodePtr cur)
+{
+    xmlChar     *key;
+    int         i, ival;
+    float       val;
+    units_list  *unit, *tmp;
+
+    unit = (units_list *)malloc(sizeof(units_list));
+    unit->next = NULL;
+    unit->version = 1;
+    unit->uuid = unit->name = unit->hlt_sensor_address = unit->hlt_heater_address = unit->mlt_sensor_address = \
+                 unit->mlt_heater_address = unit->mlt_pump_address = NULL;
+    unit->hlt_sensor_state = unit->mlt_sensor_state = 1; // missing
+    unit->hlt_heater_state = unit->mlt_heater_state = unit->mlt_pump_state = 0;
+    unit->hlt_heater_delay = unit->mlt_heater_delay = unit->mlt_pump_delay = 20;     /* 5 minutes delay */
+    unit->PID_hlt = (pid_var *)malloc(sizeof(pid_var));
+    unit->PID_mlt = (pid_var *)malloc(sizeof(pid_var));
+    InitPID(unit->PID_hlt);
+    InitPID(unit->PID_mlt);
+
+    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 *)"HLT_SENSOR_ADDRESS"))) {
+            unit->hlt_sensor_address = (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_ADDRESS"))) {
+            unit->hlt_heater_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+        }
+        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 *)"MLT_SENSOR_ADDRESS"))) {
+            unit->mlt_sensor_address = (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_ADDRESS"))) {
+            unit->mlt_heater_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+        }
+        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_ADDRESS"))) {
+            unit->mlt_pump_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+        }
+        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 *)"PID_HLT_IMAX"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->iMax = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_IGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->iGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_PGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->pGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_DGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->dGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_INPUT"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->Input = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_ERR"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->Err = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_ERRLAST"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->ErrLast = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_ISTATE"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->iState = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_SETP"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->SetP = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_OUTP"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_hlt->OutP = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_MODE"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            for (i = 0; i < 3; i++) {
+                if (! xmlStrcmp(key, (const xmlChar *)PIDMODE[i])) {
+                    unit->PID_hlt->Mode = i;
+                    break;
+                }
+            }
+            xmlFree(key);
+        }
+
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_IMAX"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->iMax = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_IGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->iGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_PGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->pGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_DGAIN"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->dGain = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_INPUT"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->Input = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_ERR"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->Err = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_ERRLAST"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->ErrLast = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_ISTATE"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->iState = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_SETP"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->SetP = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_OUTP"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &val) == 1)
+                unit->PID_mlt->OutP = val;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_MODE"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            for (i = 0; i < 3; i++) {
+                if (! xmlStrcmp(key, (const xmlChar *)PIDMODE[i])) {
+                    unit->PID_mlt->Mode = 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;
+    simulator_list      *simulator, *tmp;
+    int                 ival;
+    float               fval;
+
+    simulator = (simulator_list *)malloc(sizeof(simulator_list));
+    simulator->next = NULL;
+    simulator->version = 1;
+    simulator->uuid = simulator->name = NULL;
+    simulator->room_temperature = simulator->hlt_heater_temp = simulator->mlt_heater_temp = simulator->s_hlt_temp = simulator->s_mlt_temp = 20.0;
+    simulator->hlt_heater_temp = simulator->hlt_heater_size = simulator->mlt_heater_temp = simulator->mlt_heater_size = 0.0;
+    simulator->hlt_heater_time = simulator->mlt_heater_time = simulator->hlt_heater_state = simulator->mlt_heater_state = 0;
+    simulator->s_hlt_temp = simulator->s_mlt_temp = 0.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;
+            }
+            simulator->version = 1;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) {
+            simulator->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
+            simulator->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+        }
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOM_TEMPERATURE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		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)
+		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)
+		simulator->hlt_heater_temp = fval;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_TIME"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		simulator->hlt_heater_time = ival;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_SIZE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		simulator->hlt_heater_size = fval;
+	    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)
+		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)
+                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)
+                simulator->mlt_heater_temp = fval;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_TIME"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%d", &ival) == 1)
+                simulator->mlt_heater_time = ival;
+            xmlFree(key);
+        }
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_SIZE"))) {
+            key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+            if (sscanf((const char *)key, "%f", &fval) == 1)
+                simulator->mlt_heater_size = fval;
+            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)
+                simulator->mlt_heater_state = ival;
+            xmlFree(key);
+        }
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"S_HLT_TEMP"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		simulator->s_hlt_temp = fval;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"S_MLT_TEMP"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		simulator->s_mlt_temp = fval;
+	    xmlFree(key);
+	}
+        cur = cur->next;
+    }
+
+    if (Config.simulators == NULL) {
+        Config.simulators = simulator;
+    } else {
+        for (tmp = Config.simulators; tmp; tmp = tmp->next) {
+            if (tmp->next == NULL) {
+                tmp->next = simulator;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+
+int parseSimulators(xmlDocPtr doc, xmlNodePtr cur)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"SIMULATOR"))) {
+            parseSimulator(doc, cur);
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
 #endif
 
 
 
 int rdconfig(void) 
 {
-    int		rc = 0;
+    int		ival, rc = 0;
     char	*mypath;
     xmlDocPtr	doc;
     xmlNodePtr	cur;
@@ -369,21 +1316,36 @@
 	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 *)"HLT_SENSOR_ADDRESS"))) {
-	    Config.hlt_sensor_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_ADDRESS"))) {
+	    Config.temp_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_ADDRESS"))) {
-	    Config.mlt_sensor_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HUM_ADDRESS"))) {
+	    Config.hum_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
-#ifdef HAVE_WIRINGPI_H
 	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 *)"SIMULATORS"))) {
+	    parseSimulators(doc, cur);
+	}
 #endif
 	cur = cur->next;
     }

mercurial