thermferm/rdconfig.c

changeset 80
81bf78a7618e
parent 78
c49ab5179bf3
child 82
d48299405980
--- a/thermferm/rdconfig.c	Wed Jun 25 19:42:03 2014 +0200
+++ b/thermferm/rdconfig.c	Thu Jun 26 20:00:00 2014 +0200
@@ -73,6 +73,7 @@
 void killconfig(void)
 {
     w1_therm	*tmp1, *old1;
+    units_list	*tmp2;
 
     if (Config.name)
 	free(Config.name);
@@ -90,6 +91,26 @@
     }
     Config.w1therms = NULL;
     Config.my_port = 6554;
+    Config.tempFormat = 'C';
+
+    for (tmp2 = Config.units; tmp2; tmp2 = tmp2->next) {
+	if (tmp2->uuid)
+	    free(tmp2->uuid);
+	if (tmp2->name)
+	    free(tmp2->name);
+	if (tmp2->air_address)
+	    free(tmp2->air_address);
+	if (tmp2->beer_address)
+	    free(tmp2->beer_address);
+	if (tmp2->io1_address)
+	    free(tmp2->io1_address);
+	if (tmp2->io2_address)
+	    free(tmp2->io2_address);
+	if (tmp2->profile)
+	    free(tmp2->profile);
+	free(tmp2);
+    }
+    Config.units = NULL;
 
 #ifdef HAVE_WIRINGPI_H
     Config.lcd_cols = 16;
@@ -347,7 +368,7 @@
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", MBSE_SS(tmp3->name))) < 0) {
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", tmp3->name)) < 0) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
@@ -355,19 +376,19 @@
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "AIR_ADDRESS", "%s", MBSE_SS(tmp3->air_address))) < 0) {
+	    if (tmp3->air_address && ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "AIR_ADDRESS", "%s", tmp3->air_address)) < 0)) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEER_ADDRESS", "%s", MBSE_SS(tmp3->beer_address))) < 0) {
+	    if (tmp3->beer_address && ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEER_ADDRESS", "%s", tmp3->beer_address)) < 0)) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IO1_ADDRESS", "%s", MBSE_SS(tmp3->io1_address))) < 0) {
+	    if (tmp3->io1_address && ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IO1_ADDRESS", "%s", tmp3->io1_address)) < 0)) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IO2_ADDRESS", "%s", MBSE_SS(tmp3->io2_address))) < 0) {
+	    if (tmp3->io2_address && ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IO2_ADDRESS", "%s", tmp3->io2_address)) < 0)) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
@@ -469,11 +490,299 @@
 
 
 
+/*
+ * Parse one LCD display
+ */
+#ifdef HAVE_WIRINGPI_H
+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;
+}
+#endif
+
+
+
+int parseW1therm(xmlDocPtr doc, xmlNodePtr cur)
+{
+    xmlChar     *key;
+    int         ival;
+    w1_therm	*w1therm, *tmp;
+
+    w1therm = (w1_therm *)malloc(sizeof(w1_therm));
+    w1therm->next = NULL;
+    w1therm->master = w1therm->name = w1therm->alias = NULL;
+    w1therm->bus = w1therm->present = w1therm->lastval = w1therm->update = 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;
+	    }
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"MASTER"))) {
+	    w1therm->master = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"BUS"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		w1therm->bus = ival;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
+	    w1therm->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"ALIAS"))) {
+	    w1therm->alias = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	cur = cur->next;
+    }
+
+    if (Config.w1therms == NULL) {
+	Config.w1therms = w1therm;
+    } else {
+	for (tmp = Config.w1therms; tmp; tmp = tmp->next) {
+	    if (tmp->next == NULL) {
+		tmp->next = w1therm;
+		break;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+
+
+int parseW1therms(xmlDocPtr doc, xmlNodePtr cur)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"W1TERM"))) {
+	    parseW1therm(doc, cur);
+	}
+	cur = cur->next;
+    }
+    return 0;
+}
+
+
+
+/*
+ * Parse a fermenter unit
+ */
+int parseUnit(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->uuid = unit->name = unit->air_address = unit->beer_address = unit->io1_address = unit->io2_address = unit->profile = NULL;
+    unit->volume = 0.0;
+    unit->heater_available = unit->cooler_available = unit->fan_available = FALSE;
+    unit->air_temp = unit->beer_temp = unit->beer_set = unit->fridge_set = 20.0;
+    unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = 0;
+    unit->temp_set_min = 1.0;
+    unit->temp_set_max = 30.0;
+    unit->idle_rangeH = 1.0;
+    unit->idle_rangeL = -1.0;
+    unit->prof_started = (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;
+	    }
+	    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 *)"VOLUME"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->volume = val;
+		xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"AIR_ADDRESS"))) {
+	    unit->air_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"BEER_ADDRESS"))) {
+	    unit->beer_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"IO1_ADDRESS"))) {
+	    unit->io1_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"IO2_ADDRESS"))) {
+	    unit->io2_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HEATER"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (! xmlStrcmp(key, (const xmlChar *)"TRUE"))
+		unit->heater_available = TRUE;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"COOLER"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (! xmlStrcmp(key, (const xmlChar *)"TRUE"))
+		unit->cooler_available = TRUE;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"FAN"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (! xmlStrcmp(key, (const xmlChar *)"TRUE"))
+		unit->fan_available = TRUE;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"MODE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    for (i = 0; i < 5; i++) {
+	    	if (! xmlStrcmp(key, (const xmlChar *)UNITMODE[i])) {
+	   	    unit->mode = i;
+		    break;
+		}
+	    }
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"BEER_SET"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->beer_set = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"FRIDGE_SET"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->fridge_set = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_SET_MIN"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->temp_set_min = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_SET_MAX"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->temp_set_max = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"IDLE_RANGE_L"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->idle_rangeL = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"IDLE_RANGE_H"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->idle_rangeH = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILE"))) {
+	    unit->profile = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROF_STARTED"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		unit->prof_started = ival;
+	    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 parseFermenters(xmlDocPtr doc, xmlNodePtr cur)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"UNIT"))) {
+	    parseUnit(doc, cur);
+	}
+	cur = cur->next;
+    }
+    return 0;
+}
+
+
+
 int rdconfig(char *config) 
 {
-    char	buf[256], *p;
-    FILE	*fp;
-    int		i, rc = 0;
+//    char	buf[256], *p;
+//    FILE	*fp;
+//    int		i, rc = 0;
+    int		rc = 0, ival;
+    xmlDocPtr	doc;
+    xmlNodePtr	cur;
+    xmlChar	*key;
 
     killconfig();
 
@@ -489,28 +798,78 @@
     }
     mypath = xstrcat(mypath, (char *)"/mbsepi-apps/");
     mypath = xstrcat(mypath, config);
-    if ((fp = fopen(mypath, "r")) == NULL) {
+    if ((doc = xmlParseFile(mypath)) == NULL) {
+    //if ((fp = fopen(mypath, "r")) == NULL) {
 	/*
 	 * Not in the users home directory
 	 */
 	free(mypath);
 	mypath = xstrcpy((char *)"/etc/mbsepi-apps/");
 	mypath = xstrcat(mypath, config);
-	if ((fp = fopen(mypath, "r")) == NULL) {
+	if ((doc = xmlParseFile(mypath)) == NULL) {
+	//if ((fp = fopen(mypath, "r")) == NULL) {
 	    /*
 	     * Try /usr/local/etc
 	     */
 	    free(mypath);
 	    mypath = xstrcpy((char *)"/usr/local/etc/mbsepi-apps/");
 	    mypath = xstrcat(mypath, config);
-	    if ((fp = fopen(mypath, "r")) == NULL) {
-		syslog(LOG_NOTICE, "rdconfig: could find %s", config);
+	    if ((doc = xmlParseFile(mypath)) == NULL) {
+	    //if ((fp = fopen(mypath, "r")) == NULL) {
+		syslog(LOG_NOTICE, "rdconfig: could not parse %s", config);
 		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*)"THERMFERM")) {
+	syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.\n", mypath);
+	xmlFreeDoc(doc);
+	return 1;
+    }
+
+    /*
+     * Parse configuration
+     */
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	    // VERSION LISTEN_PORT TEMPFORMAT LCDS FERMENTERS
+//	if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) {
+//	    recipe->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);
+	}
+#ifdef HAVE_WIRINGPI_H
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCDS"))) {
+	    parseLCDs(doc, cur);
+	}
+#endif
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"W1TERMS"))) {
+	    parseW1therms(doc, cur);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"FERMENTERS"))) {
+	    parseFermenters(doc, cur);
+	}
+	cur = cur->next;
+    }
+    xmlFreeDoc(doc);
+
+    /*
     linecnt = 0;
     while (fgets(buf, sizeof(buf) -1, fp)) {
 	linecnt++;
@@ -552,6 +911,7 @@
 
     }
     fclose(fp);
+    */
 
     free(mypath);
     mypath = NULL;

mercurial