Added fermenting profiles to the configuration

Thu, 03 Jul 2014 23:11:44 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 03 Jul 2014 23:11:44 +0200
changeset 91
901ca9858a7a
parent 90
28ee293654fd
child 92
116226a8c70a

Added fermenting profiles to the configuration

thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
--- a/thermferm/rdconfig.c	Wed Jul 02 22:41:31 2014 +0200
+++ b/thermferm/rdconfig.c	Thu Jul 03 23:11:44 2014 +0200
@@ -37,15 +37,16 @@
 
 void killconfig(void)
 {
-    w1_therm	*tmp1, *old1;
-    units_list	*tmp2;
+    w1_therm		*tmp1;
+    units_list		*tmp2;
+    profiles_list	*tmp3;
+    prof_step		*tmp4;
 
     if (Config.name)
 	free(Config.name);
     Config.name = NULL;
 
-    for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) {
-	old1 = tmp1->next;
+    for (tmp1 = Config.w1therms; tmp1; tmp1 = tmp1->next) {
 	if (tmp1->master)
 	    free(tmp1->master);
 	if (tmp1->name)
@@ -77,6 +78,20 @@
     }
     Config.units = NULL;
 
+    for (tmp3 = Config.profiles; tmp3; tmp3 = tmp3->next) {
+	if (tmp3->uuid)
+	    free(tmp3->uuid);
+	if (tmp3->name)
+	    free(tmp3->name);
+	if (tmp3->steps) {
+	    for (tmp4 = tmp3->steps; tmp4; tmp4 = tmp4->next) {
+		free(tmp4);
+	    }
+	}
+	free(tmp3);
+    }
+    Config.profiles = NULL;
+
 #ifdef HAVE_WIRINGPI_H
     Config.lcd_cols = 16;
     Config.lcd_rows = 2;
@@ -96,6 +111,8 @@
     xmlBufferPtr	buf;
     w1_therm    	*tmp1;
     units_list		*tmp3;
+    profiles_list	*tmp4;
+    prof_step		*tmp5;
 
     /* 
      * Create a new XML buffer, to which the XML document will be written
@@ -363,6 +380,74 @@
     }
 
     /*
+     * Fermenting profiles
+     */
+    if (Config.profiles) {
+	if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "PROFILES")) < 0) {
+	    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+	    return 1;
+	}
+	for (tmp4 = Config.profiles; tmp4; tmp4 = tmp4->next) {
+	    if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "PROFILE")) < 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", tmp4->uuid)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", tmp4->name)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if (tmp4->steps) {
+		if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "STEPS")) < 0) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+		    return 1;
+		}
+		for (tmp5 = tmp4->steps; tmp5; tmp5 = tmp5->next) {
+		    if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "STEP")) < 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 "DURATION", "%d", tmp5->duration)) < 0) {
+		        syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+			return 1;
+		    }
+		    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TARGET", "%.1f", tmp5->target)) < 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 ((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;
+	}
+    }
+
+    /*
      * All done, close any open elements
      */
     if ((rc = xmlTextWriterEndDocument(writer)) < 0) {
@@ -686,8 +771,140 @@
 {
     cur = cur->xmlChildrenNode;
     while (cur != NULL) {
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"UNIT"))) {
-	    parseUnit(doc, cur);
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"UNIT"))) {
+            parseUnit(doc, cur);
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
+
+
+
+int parseStep(xmlDocPtr doc, xmlNodePtr cur, prof_step **profstep)
+{
+    xmlChar     *key;
+    int         ival;
+    float       val;
+    prof_step	*step, *tmp;
+
+    step = (prof_step *)malloc(sizeof(prof_step));
+    step->next = NULL;
+    step->version = 1;
+    step->duration = 0;
+    step->target = 20.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;
+	    }
+	    step->version = 1;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DURATION"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		step->duration = ival;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TARGET"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		step->target = val;
+	    xmlFree(key);
+	}
+	cur = cur->next;
+    }
+
+    if (*profstep == NULL) {
+	*profstep = step;
+    } else {
+	for (tmp = *profstep; tmp; tmp = tmp->next) {
+	    if (tmp->next == NULL) {
+		tmp->next = step;
+		break;
+	    }
+	}
+    }
+    return 0;
+}
+
+
+
+int parseSteps(xmlDocPtr doc, xmlNodePtr cur, prof_step **step)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"STEP"))) {
+	    parseStep(doc, cur, step);
+	}
+	cur = cur->next;
+    }
+    return 0;
+}
+
+
+
+int parseProfile(xmlDocPtr doc, xmlNodePtr cur)
+{
+    xmlChar     	*key;
+    profiles_list	*profile, *tmp;
+
+    profile = (profiles_list *)malloc(sizeof(profiles_list));
+    profile->next = NULL;
+    profile->version = 1;
+    profile->uuid = profile->name = NULL;
+    profile->steps = NULL;
+
+    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;
+	    }
+	    profile->version = 1;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) {
+	    profile->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
+	    profile->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"STEPS"))) {
+	    parseSteps(doc, cur, &(profile)->steps);
+	}
+	cur = cur->next;
+    }
+
+    if (Config.profiles == NULL) {
+	Config.profiles = profile;
+    } else {
+	for (tmp = Config.profiles; tmp; tmp = tmp->next) {
+	    if (tmp->next == NULL) {
+		tmp->next = profile;
+		break;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+
+
+int parseProfiles(xmlDocPtr doc, xmlNodePtr cur)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILE"))) {
+	    parseProfile(doc, cur);
 	}
 	cur = cur->next;
     }
@@ -784,6 +1001,9 @@
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"FERMENTERS"))) {
 	    parseFermenters(doc, cur);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILES"))) {
+	    parseProfiles(doc, cur);
+	}
 	cur = cur->next;
     }
     xmlFreeDoc(doc);
--- a/thermferm/thermferm.h	Wed Jul 02 22:41:31 2014 +0200
+++ b/thermferm/thermferm.h	Thu Jul 03 23:11:44 2014 +0200
@@ -51,12 +51,6 @@
 
 #define MBSE_SS(x) (x)?(x):"(null)"
 
-/* rdconfig.c */
-//typedef struct _key_list {
-//    char		*key;
-//    int			(*prc)(char **);
-//    char		**dest;
-//} key_list;
 
 /*
  * Fermenter units. These units are connected via the 1-wire bus.
@@ -108,6 +102,29 @@
 #define	UNITIO2_FAN		0x01		/* Fan bit			*/
 #define	UNITIO2_DOOR		0x02		/* Door status			*/
 
+
+
+/*
+ * Fermenting steps
+ */
+typedef struct _prof_step {
+    struct _prof_step	*next;
+    int			version;		/* Version 1			*/
+    int			duration;		/* Duration in hours		*/
+    float		target;			/* Target temperature		*/
+} prof_step;
+
+/*
+ * Fermenting profiles
+ */
+typedef struct _prof_list {
+    struct _prof_list	*next;
+    int			version;		/* Version 1			*/
+    char		*uuid;			/* Profile uuid			*/
+    char		*name;			/* Profile name			*/
+    prof_step		*steps;			/* Profile steps		*/
+} profiles_list;
+
 #define PROFILE_OFF		0		/* Profile not active		*/
 #define	PROFILE_PAUSE		1		/* Profile pause		*/
 #define	PROFILE_RUN		2		/* Profile is running		*/
@@ -136,6 +153,7 @@
     int			lcd_address;		/* LCD display i2c address	*/
 #endif
     units_list		*units;			/* Fermenter units		*/
+    profiles_list	*profiles;		/* Ferment profiles		*/
     						/* ControlSettings:		*/
     unsigned char	cs_mode;		/* mode				*/
     float		cs_beerSet;		/* beer temperature		*/

mercurial