# HG changeset patch # User Michiel Broek # Date 1404496819 -7200 # Node ID 116226a8c70a3e845b4566867227b4b286d95baf # Parent 901ca9858a7a83cc8f708e320284161c3ed4c65b Added profiles configuration diff -r 901ca9858a7a -r 116226a8c70a thermferm/rdconfig.c --- a/thermferm/rdconfig.c Thu Jul 03 23:11:44 2014 +0200 +++ b/thermferm/rdconfig.c Fri Jul 04 20:00:19 2014 +0200 @@ -418,10 +418,14 @@ syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); return 1; } - if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DURATION", "%d", tmp5->duration)) < 0) { + if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "RESTTIME", "%d", tmp5->resttime)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } + if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "STEPTIME", "%d", tmp5->steptime)) < 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; @@ -791,7 +795,7 @@ step = (prof_step *)malloc(sizeof(prof_step)); step->next = NULL; step->version = 1; - step->duration = 0; + step->steptime = step->resttime = 0; step->target = 20.0; cur = cur->xmlChildrenNode; @@ -805,10 +809,16 @@ step->version = 1; xmlFree(key); } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DURATION"))) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"RESTTIME"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (sscanf((const char *)key, "%d", &ival) == 1) - step->duration = ival; + step->resttime = ival; + xmlFree(key); + } + if ((!xmlStrcmp(cur->name, (const xmlChar *)"STEPTIME"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if (sscanf((const char *)key, "%d", &ival) == 1) + step->steptime = ival; xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"TARGET"))) { diff -r 901ca9858a7a -r 116226a8c70a thermferm/server.c --- a/thermferm/server.c Thu Jul 03 23:11:44 2014 +0200 +++ b/thermferm/server.c Fri Jul 04 20:00:19 2014 +0200 @@ -107,58 +107,97 @@ /* - * ADD name + * ADD PROFILE name + * ADD UNIT name */ int unit_add(char *buf) { - units_list *unit, *tmp; - uuid_t uu; - char *cmd, *opt; - int id = 1; + units_list *unit, *tmpu; + profiles_list *profile, *tmpp; + uuid_t uu; + char *opt, *param; + int id = 1; - cmd = strtok(buf, " \0"); - opt = strtok(NULL, "\0"); + opt = strtok(buf, " \0"); + opt = strtok(NULL, " \0"); if (opt == NULL) { + srv_send((char *)"501 Subcommand missing"); + return 1; + } + + param = strtok(NULL, "\0"); + if (param == NULL) { srv_send((char *)"501 Parameter missing"); return 1; } if (debug) - fprintf(stdout, "cmd: '%s' opt: '%s'\n", MBSE_SS(cmd), MBSE_SS(opt)); + fprintf(stdout, "opt: '%s' param: '%s'\n", MBSE_SS(opt), MBSE_SS(param)); - unit = (units_list *)malloc(sizeof(units_list)); - unit->next = NULL; - unit->uuid = malloc(37); - uuid_generate(uu); - uuid_unparse(uu, unit->uuid); - unit->name = xstrcpy(opt); - 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; + if (strcmp(opt, (char *)"PROFILE") == 0) { + profile = (profiles_list *)malloc(sizeof(profiles_list)); + profile->next = NULL; + profile->version = 1; + profile->uuid = malloc(37); + uuid_generate(uu); + uuid_unparse(uu, profile->uuid); + profile->name = xstrcpy(param); + profile->steps = NULL; - if (Config.units == NULL) { - Config.units = unit; - } else { - for (tmp = Config.units; tmp; tmp = tmp->next) { - id++; - if (tmp->next == NULL) { - tmp->next = unit; - break; + if (Config.profiles == NULL) { + Config.profiles = profile; + } else { + for (tmpp = Config.profiles; tmpp; tmpp = tmpp->next) { + if (tmpp->next == NULL) { + tmpp->next = profile; + break; + } } } + + syslog(LOG_NOTICE, "Profile \"%s\" with uuid %s added", param, profile->uuid); + srv_send((char *)"211 Profile \"%s\" with uuid %s added", param, profile->uuid); + return 0; + + } else if (strcmp(opt, (char *)"UNIT") == 0) { + unit = (units_list *)malloc(sizeof(units_list)); + unit->next = NULL; + unit->version = 1; + unit->uuid = malloc(37); + uuid_generate(uu); + uuid_unparse(uu, unit->uuid); + unit->name = xstrcpy(param); + 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 = unit->prof_state = 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; + + if (Config.units == NULL) { + Config.units = unit; + } else { + for (tmpu = Config.units; tmpu; tmpu = tmpu->next) { + id++; + if (tmpu->next == NULL) { + tmpu->next = unit; + break; + } + } + } + + syslog(LOG_NOTICE, "Unit %d with uuid %s added", id, unit->uuid); + srv_send((char *)"211 Unit %d with uuid %s added", id, unit->uuid); + current_unit = id; + return 0; } - syslog(LOG_NOTICE, "Unit %d with uuid %s added", id, unit->uuid); - srv_send((char *)"211 Unit %d with uuid %s added", id, unit->uuid); - current_unit = id; - return 0; + srv_send((char *)"502 Unknown command option"); + return 1; } @@ -171,16 +210,20 @@ */ int cmd_list(char *buf) { - char *opt, *mypath; + char *opt; units_list *unit; + profiles_list *profile; int i; DIR *fd; struct dirent *de; opt = strtok(buf, " \0"); - opt = strtok(NULL, " \0"); + opt = strtok(NULL, "\0"); if (opt == NULL) { + /* + * Default, list available units + */ srv_send((char *)"212 Fermenter list follows:"); i = 0; for (unit = Config.units; unit; unit = unit->next) { @@ -188,6 +231,8 @@ srv_send((char *)"%02d %s %-20s %-7s", i, unit->uuid, unit->name, UNITMODE[unit->mode]); } srv_send((char *)"."); + return 0; + } else if (strcmp(opt, (char *)"BUS") == 0) { /* * 1-wire bus @@ -213,88 +258,80 @@ } srv_send((char *)"."); closedir(fd); + return 0; } else { srv_send((char *)"503 directory /sys/bus/w1/devices: %s", strerror(errno)); + return 1; } + } else if (strcmp(opt, (char *)"PROFILES") == 0) { /* - * User profiles directory + * Fermenting profiles */ - if (getenv((char *)"USER") == NULL) { - mypath = xstrcpy((char *)"/root"); - } else { - mypath = xstrcpy(getenv((char *)"HOME")); + srv_send((char *)"212 profiles:"); + i = 0; + for (profile = Config.profiles; profile; profile = profile->next) { + i++; + srv_send((char *)"%02d %s %s", i, profile->uuid, profile->name); } - mypath = xstrcat(mypath, (char *)"/.thermferm/profiles/"); - mkdirs(mypath, 0755); - if ((fd = opendir(mypath))) { - srv_send((char *)"212 profiles:"); - while ((de = readdir(fd))) { - if (de->d_name[0] != '.') { - srv_send((char *)"%s", de->d_name); - } - } - srv_send((char *)"."); - closedir(fd); - } else { - srv_send((char *)"503 directory %s: %s", mypath, strerror(errno)); - } - free(mypath); - mypath = NULL; + srv_send((char *)"."); + return 0; + } else if (strcmp(opt, (char *)"UNIT") == 0) { /* * List configured and selected fermenter unit */ if (current_unit == -1) { srv_send((char *)"401 No fermenter unit selected"); - } else { - srv_send((char *)"213 Unit %d listing follows:", current_unit); - i = 0; - for (unit = Config.units; unit; unit = unit->next) { - i++; - if (i == current_unit) { - srv_send((char *)"Name of the unit/beer %s", unit->name); - srv_send((char *)"UUID of this unit %s", unit->uuid); - if (unit->air_address) { - srv_send((char *)"1-wire address air sensor %s", unit->air_address); - srv_send((char *)"Air temperature %.1f", unit->air_temp); - } - if (unit->beer_address) { - srv_send((char *)"1-wire address beer sensor %s", unit->air_address); - srv_send((char *)"Beer temperature %.1f", unit->air_temp); - } - if (unit->io1_address) { - srv_send((char *)"1-wire address cool/heat %s", unit->io1_address); - } - if (unit->io2_address) { - srv_send((char *)"1-wire address fan/door %s", unit->io2_address); - } - if (unit->heater_available) { - srv_send((char *)"Heater available %s", unit->heater_available); - } - if (unit->cooler_available) { - srv_send((char *)"Cooler available %s", unit->cooler_available); - } - if (unit->fan_available) { - srv_send((char *)"Fan available %s", unit->fan_available); - } - srv_send((char *)"Unit mode %s", UNITMODE[unit->mode]); - srv_send((char *)"Fridge temperature set to %.1f", unit->fridge_set); - srv_send((char *)"Beer temperature set to %.1f", unit->beer_set); - if (unit->profile) { - srv_send((char *)"Profile name %s", unit->profile); - } - srv_send((char *)"Temperature range %.1f .. %.1f", unit->temp_set_min, unit->temp_set_max); - srv_send((char *)"Idle temperature range %.1f .. %.1f", unit->idle_rangeL, unit->idle_rangeH); + return 1; + } + + srv_send((char *)"213 Unit %d listing follows:", current_unit); + i = 0; + for (unit = Config.units; unit; unit = unit->next) { + i++; + if (i == current_unit) { + srv_send((char *)"Name of the unit/beer %s", unit->name); + srv_send((char *)"UUID of this unit %s", unit->uuid); + if (unit->air_address) { + srv_send((char *)"1-wire address air sensor %s", unit->air_address); + srv_send((char *)"Air temperature %.1f", unit->air_temp); + } + if (unit->beer_address) { + srv_send((char *)"1-wire address beer sensor %s", unit->air_address); + srv_send((char *)"Beer temperature %.1f", unit->air_temp); + } + if (unit->io1_address) { + srv_send((char *)"1-wire address cool/heat %s", unit->io1_address); } + if (unit->io2_address) { + srv_send((char *)"1-wire address fan/door %s", unit->io2_address); + } + if (unit->heater_available) { + srv_send((char *)"Heater available %s", unit->heater_available); + } + if (unit->cooler_available) { + srv_send((char *)"Cooler available %s", unit->cooler_available); + } + if (unit->fan_available) { + srv_send((char *)"Fan available %s", unit->fan_available); + } + srv_send((char *)"Unit mode %s", UNITMODE[unit->mode]); + srv_send((char *)"Fridge temperature set to %.1f", unit->fridge_set); + srv_send((char *)"Beer temperature set to %.1f", unit->beer_set); + if (unit->profile) { + srv_send((char *)"Profile name %s", unit->profile); + } + srv_send((char *)"Temperature range %.1f .. %.1f", unit->temp_set_min, unit->temp_set_max); + srv_send((char *)"Idle temperature range %.1f .. %.1f", unit->idle_rangeL, unit->idle_rangeH); } - srv_send((char *)"."); } - } else { - srv_send((char *)"502 Unknown command option"); + srv_send((char *)"."); + return 0; } - return 0; + srv_send((char *)"502 Unknown command option"); + return 1; } @@ -311,7 +348,15 @@ /* - * SET commands + * SET BEER float + * SET FRIDGE float + * SET VOLUME float + * SET IDLE_LOW float + * SET IDLE_HIGH float + * SET TEMP_MIN float + * SET TEMP_MAX float + * SET NAME string + * SET PROFILE string */ int cmd_set(char *buf) { @@ -513,12 +558,6 @@ int j; #endif -// if (debug) { -// char *hostname = inet_ntoa(peeraddr_in.sin_addr); -// syslog(LOG_NOTICE, "Start new client connection from %s port %u", hostname, ntohs(peeraddr_in.sin_port)); -// fprintf(stdout, "Start new client connection from %s port %u\n", hostname, ntohs(peeraddr_in.sin_port)); -// } - memset((char *)&buf, 0, SS_BUFSIZE); fromlen = sizeof(peeraddr_in); rlen = recvfrom(s, buf, sizeof(buf) -1, 0, (struct sockaddr *)&peeraddr_in, &fromlen); @@ -547,12 +586,14 @@ * Process commands from the client */ if (strncmp(buf, "ADD", 3) == 0) { - unit_add(buf); + if (unit_add(buf) == 0) + wrconfig(); } else if (strncmp(buf, "HELP", 4) == 0) { srv_send((char *)"100 Help text follows"); srv_send((char *)"Recognized commands:"); srv_send((char *)""); - srv_send((char *)"ADD name Add a new unit with \"name\""); + srv_send((char *)"ADD PROFILE name Add a new profile with \"name\""); + srv_send((char *)"ADD UNIT name Add a new unit with \"name\""); srv_send((char *)"LCD Get LCD screen (allways 4 rows of 20 characters)"); srv_send((char *)"LIST List all fermenter units"); srv_send((char *)"LIST BUS List 1-wire bus"); @@ -591,7 +632,8 @@ } else if (strncmp(buf, "MODE", 4) == 0) { cmd_mode(buf); } else if (strncmp(buf, "SET", 3) == 0) { - cmd_set(buf); + if (cmd_set(buf) == 0) + wrconfig(); } else if (strncmp(buf, "UNIT", 4) == 0) { cmd_unit(buf); } else if (strncmp(buf, "ack", 3) == 0) { diff -r 901ca9858a7a -r 116226a8c70a thermferm/thermferm.h --- a/thermferm/thermferm.h Thu Jul 03 23:11:44 2014 +0200 +++ b/thermferm/thermferm.h Fri Jul 04 20:00:19 2014 +0200 @@ -110,7 +110,8 @@ typedef struct _prof_step { struct _prof_step *next; int version; /* Version 1 */ - int duration; /* Duration in hours */ + int steptime; /* Step time to target in hours */ + int resttime; /* Rest time on target in hours */ float target; /* Target temperature */ } prof_step;