thermferm/mqtt.c

changeset 570
1e0192b295b9
parent 569
9c69d43bfb06
child 571
6f8eda55ec2c
--- a/thermferm/mqtt.c	Thu Jan 10 16:33:42 2019 +0100
+++ b/thermferm/mqtt.c	Mon Jan 14 22:46:27 2019 +0100
@@ -21,6 +21,7 @@
  *****************************************************************************/
 
 #include "thermferm.h"
+#include "rdconfig.h"
 #include "logger.h"
 #include "devices.h"
 #include "xutil.h"
@@ -152,7 +153,7 @@
 
 void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str)
 {
-    syslog(LOG_NOTICE, "MQTT: %s", str);
+//    syslog(LOG_NOTICE, "MQTT: %s", str);
     if (debug)
     	fprintf(stdout, "MQTT: %s\n", str);
 }
@@ -163,7 +164,8 @@
 {
     char		*message_type, *message_node, *message_alias;
     units_list		*unit;
-    struct json_object	*jobj, *metric, *val, *setpoint;
+    prof_step           *step, *oldstep;
+    struct json_object	*jobj, *metric, *val, *setpoint, *profile, *profile1, *steps, *step1;
     time_t		timestamp;
     int			timediff;
 
@@ -205,13 +207,16 @@
 			    return;
 			}
 		    }
+
+		    /*
+		     * DCMD, commands and configuration changes for a single fermenter.
+		     */
 		    if ((strcmp(message_type, "DCMD") == 0) && message_node && message_alias) {
 			syslog(LOG_NOTICE, "%s", (char *)json_object_get_string(metric));
 			for (unit = Config.units ; unit; unit = unit->next) {
 			    if (strcmp(unit->alias, message_alias) == 0) {
 				syslog(LOG_NOTICE, "MQTT: DCMD for %s/%s", (char *)message_node, (char *)message_alias);
 			    	if (json_object_object_get_ex(metric, "stage", &val)) {
-		//		    syslog(LOG_NOTICE, "Change state %s", UNITSTAGE[unit->stage]);
 				    for (int i = 0; i < 4; i++) {
 					if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) {
 				    	    if (unit->stage != i) {
@@ -223,7 +228,7 @@
 					}
 				    }
 			    	}
-				printf("start mode\n");
+
 				if (json_object_object_get_ex(metric, "mode", &val)) {
 				    for (int i = 0; i < 4; i++) {
 					if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) {
@@ -255,7 +260,7 @@
 						     */
 						    unit->prof_target_lo = unit->prof_target_hi = 20.0;
 						    unit->prof_fridge_mode = 0;
-						    if (unit->profile) {
+						    if (unit->profile_uuid) {
 							unit->mqtt_flag |= MQTT_FLAG_DATA;
 						    }
 						}
@@ -264,28 +269,25 @@
 					}
 				    }
 				}
-				printf("start setpoint\n");
+
 				if (json_object_object_get_ex(metric, "setpoint", &setpoint)) {
 				    if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) {
 					/*
-					 * Only set new setpoints if running as FRIDGE or in BEER mode.
+					 * Only set new setpoints if running in FRIDGE or in BEER mode.
 					 */
-				        if (json_object_object_get_ex(setpoint, "low", &val)) {
+				        if (json_object_object_get_ex(setpoint, "low", &val))
 					    unit->PID_heat->SetP = json_object_get_double(val);
-				    	}
-				    	if (json_object_object_get_ex(setpoint, "high", &val)) {
+				    	if (json_object_object_get_ex(setpoint, "high", &val))
 					    unit->PID_cool->SetP = json_object_get_double(val);
-				    	}
-					if (unit->mode == UNITMODE_FRIDGE) {
+					if (unit->mode == UNITMODE_FRIDGE)
 					    unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2);
-					} else {
+					else
 					    unit->beer_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2);
-					}
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
 					syslog(LOG_NOTICE, "DCMD change fermenter %s: setpoints %.1f %.1f", message_alias, unit->PID_heat->SetP, unit->PID_cool->SetP);
 				    }
 				}
-				printf("start heater\n");
+
 				if ((json_object_object_get_ex(metric, "heater", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
 				    if (json_object_object_get_ex(setpoint, "state", &val)) {
 					if (json_object_get_int(val) != unit->heater_state) {
@@ -297,6 +299,7 @@
 					}
 				    }
 				}
+
 				if ((json_object_object_get_ex(metric, "cooler", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
 				    if (json_object_object_get_ex(setpoint, "state", &val)) {
 					if (json_object_get_int(val) != unit->cooler_state) {
@@ -308,6 +311,7 @@
 					}
 				    }
 				}
+
 				if ((json_object_object_get_ex(metric, "fan", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
 				    if (json_object_object_get_ex(setpoint, "state", &val)) {
 					if (json_object_get_int(val) != unit->fan_state) {
@@ -317,6 +321,7 @@
 					}
 				    }
 				}
+
 				if ((json_object_object_get_ex(metric, "light", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
 				    if (json_object_object_get_ex(setpoint, "state", &val)) {
 					if (json_object_get_int(val) != unit->light_state) {
@@ -326,7 +331,7 @@
 					}
 				    }
 				}
-				printf("start product\n");
+
 				if ((json_object_object_get_ex(metric, "product", &setpoint)) && (unit->mode == UNITMODE_OFF)) {
 				    if (json_object_object_get_ex(setpoint, "code", &val)) {
 					if (strcmp((char *)json_object_get_string(val), unit->product_code)) {
@@ -345,11 +350,134 @@
 					}
 				    }
 				}
+
+				if (json_object_object_get_ex(metric, "profile", &profile)) {
+				    if (json_object_object_get_ex(profile, "command", &profile1)) {
+					syslog(LOG_NOTICE, "profile command");
+
+				    } else if (json_object_object_get_ex(profile, "uuid", &profile1)) {
+//					syslog(LOG_NOTICE, "profile new profile");
+					if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) {
+					    if (unit->profile_uuid)
+						free(unit->profile_uuid);
+					    if (unit->profile_name)
+						free(unit->profile_name);
+					    if (unit->profile_steps) {
+						for (step = unit->profile_steps; step; step = oldstep) {
+						    if (step->name)
+							free(step->name);
+						    oldstep = step->next;
+						    free(step);
+						}
+					    }
+					    unit->profile_steps = NULL;
+					    unit->profile_duration = unit->profile_totalsteps = 0;
+//					    syslog(LOG_NOTICE, "profile new profile: old cleared");
+
+					    unit->profile_uuid = xstrcpy((char *)json_object_get_string(profile1));
+					    if (json_object_object_get_ex(profile, "name", &val)) {
+						unit->profile_name = xstrcpy((char *)json_object_get_string(val));
+					    }
+					    if (json_object_object_get_ex(profile, "inittemp", &setpoint)) {
+						if (json_object_object_get_ex(setpoint, "low", &val)) {
+						    unit->profile_inittemp_lo = json_object_get_double(val);
+						}
+						if (json_object_object_get_ex(setpoint, "high", &val)) {
+						    unit->profile_inittemp_hi = json_object_get_double(val);
+						}
+					    }
+					    if (json_object_object_get_ex(profile, "fridgemode", &val)) {
+						unit->profile_fridge_mode = json_object_get_int(val);
+						if (unit->profile_fridge_mode)
+						    unit->profile_fridge_mode = 100;
+					    }
+					    if (json_object_object_get_ex(profile, "steps", &steps)) {
+						int arraylen = json_object_array_length(steps);
+						syslog(LOG_NOTICE, "profile new profile: start %d steps", arraylen);
+						for (int i = 0; i < arraylen; i++) {
+						    /*
+						     * Parse the array of steps
+						     */
+						    step1 = json_object_array_get_idx(steps, i);
+						    unit->profile_totalsteps++;
+
+						    step = (prof_step *)malloc(sizeof(prof_step));
+						    step->next = NULL;
+						    step->name = NULL;
+						    step->steptime = step->resttime = step->fridge_mode = 0;
+						    step->target_lo = step->target_hi = 20.0;
+
+						    if (json_object_object_get_ex(step1, "name", &val)) {
+							step->name = xstrcpy((char *)json_object_get_string(val));
+						    }
+						    if (json_object_object_get_ex(step1, "steptime", &val)) {
+							step->steptime = json_object_get_int(val);
+							unit->profile_duration += step->steptime;
+						    }
+						    if (json_object_object_get_ex(step1, "resttime", &val)) {
+							step->resttime = json_object_get_int(val);
+							unit->profile_duration += step->resttime;
+						    }
+						    if (json_object_object_get_ex(step1, "fridgemode", &val)) {
+							step->fridge_mode = json_object_get_int(val);
+							if (step->fridge_mode)
+							    step->fridge_mode = 100;
+						    }
+						    if (json_object_object_get_ex(step1, "target_lo", &val)) {
+							step->target_lo = json_object_get_double(val);
+						    }
+						    if (json_object_object_get_ex(step1, "target_hi", &val)) {
+							step->target_hi = json_object_get_double(val);
+						    }
+
+						    syslog(LOG_NOTICE, "profile new profile: add step %d", unit->profile_totalsteps);
+						    if (unit->profile_steps == NULL) {
+							unit->profile_steps = step;
+						    } else {
+							for (oldstep = unit->profile_steps; oldstep; oldstep = oldstep->next) {
+							    if (oldstep->next == NULL) {
+								oldstep->next = step;
+								break;
+							    }
+							}
+						    }
+					    	}
+					    }
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: install profile `%s'", message_alias, unit->profile_name);
+					    wrconfig();
+					}
+				    } else {
+					if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) {
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: delete profile `%s'", message_alias, unit->profile_name);
+					    if (unit->profile_uuid)
+						free(unit->profile_uuid);
+					    if (unit->profile_name)
+						free(unit->profile_name);
+					    unit->profile_uuid = unit->profile_name = NULL;
+					    if (unit->profile_steps) {
+						for (step = unit->profile_steps; step; step = oldstep) {
+						    if (step->name)
+							free(step->name);
+						    oldstep = step->next;
+						    free(step);
+						}
+					    }
+					    unit->profile_steps = NULL;
+					    unit->profile_inittemp_lo = unit->profile_inittemp_hi = 20.0;
+					    unit->prof_percent = unit->profile_fridge_mode = 0;
+					    unit->prof_state = PROFILE_OFF;
+					    unit->profile_duration = unit->profile_totalsteps = 0;
+					    unit->prof_started = unit->prof_paused = unit->prof_primary_done = (time_t)0;
+					    unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    wrconfig();
+					}
+				    }
+				}
 			    }
+
 			    if (unit->mqtt_flag) {
-			    	printf("do mqtt flag\n");
-			        if (debug)
-				    fprintf(stdout, "flag value %d\n", unit->mqtt_flag);
 			    	if (unit->mqtt_flag & MQTT_FLAG_BIRTH) {
 				    publishDBirth(unit);
 			    	} else {
@@ -360,12 +488,9 @@
 			    	}
 			    	unit->mqtt_flag |= MQTT_FLAG_DLOG;      // Something to log
 			    }
-			    printf("einde unit %s\n", unit->alias);
 			}
-			printf("return\n");
 			return;
 		    }
-		    printf("metric: %s\n", (char *)json_object_get_string(metric));
 		    syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload);
 		    return;
 		}
@@ -447,7 +572,6 @@
     char		*payload = NULL;
     char		buf[128];
     bool		comma = false;
-    profiles_list       *profile;
     prof_step           *pstep;
 
     payload = xstrcpy((char *)"{");
@@ -618,7 +742,7 @@
 	payload = xstrcat(payload, (char *)",\"door\":{\"address\":\"");
 	payload = xstrcat(payload, unit->door_address);
 	payload = xstrcat(payload, (char *)"\",\"state\":");
-	sprintf(buf, "%d", unit->door_state);
+	sprintf(buf, "%d", (unit->door_state) ? 0:1);
 	payload = xstrcat(payload, buf);
 	payload = xstrcat(payload, (char *)"}");
     } else {
@@ -659,59 +783,59 @@
     /*
      * Loaded profile and state
      */
-    if (unit->profile) {
-	for (profile = Config.profiles; profile; profile = profile->next) {
-	    if (strcmp(unit->profile, profile->uuid) == 0) {
-		payload = xstrcat(payload, (char *)",\"profile\":{\"uuid\":\"");
-		payload = xstrcat(payload, unit->profile);
-		payload = xstrcat(payload, (char *)"\",\"name\":\"");
-		payload = xstrcat(payload, profile->name);
-		payload = xstrcat(payload, (char *)"\",\"state\":\"");
-		payload = xstrcat(payload, (char *)PROFSTATE[unit->prof_state]);
-		payload = xstrcat(payload, (char *)"\",\"percent\":");
-		sprintf(buf, "%d", unit->prof_percent);
+    if (unit->profile_uuid) {
+	payload = xstrcat(payload, (char *)",\"profile\":{\"uuid\":\"");
+	payload = xstrcat(payload, unit->profile_uuid);
+	payload = xstrcat(payload, (char *)"\",\"name\":\"");
+	payload = xstrcat(payload, unit->profile_name);
+	payload = xstrcat(payload, (char *)"\",\"state\":\"");
+	payload = xstrcat(payload, (char *)PROFSTATE[unit->prof_state]);
+	payload = xstrcat(payload, (char *)"\",\"percent\":");
+	sprintf(buf, "%d", unit->prof_percent);
+	payload = xstrcat(payload, buf);
+	payload = xstrcat(payload, (char *)",\"inittemp\":{\"low\":");
+	sprintf(buf, "%.1f", unit->profile_inittemp_lo);
+	payload = xstrcat(payload, buf);
+	payload = xstrcat(payload, (char *)",\"high\":");
+	sprintf(buf, "%.1f", unit->profile_inittemp_hi);
+	payload = xstrcat(payload, buf);
+	payload = xstrcat(payload, (char *)"},\"fridgemode\":");
+	sprintf(buf, "%d", unit->profile_fridge_mode);
+	payload = xstrcat(payload, buf);
+	comma = false;
+	if (unit->profile_steps) {
+	    payload = xstrcat(payload, (char *)",\"steps\":[");
+	    for (pstep = unit->profile_steps; pstep; pstep = pstep->next) {
+		if (comma)
+		    payload = xstrcat(payload, (char *)",");
+		payload = xstrcat(payload, (char *)"{\"resttime\":");
+		sprintf(buf, "%d", pstep->resttime);
 		payload = xstrcat(payload, buf);
-		payload = xstrcat(payload, (char *)",\"inittemp\":{\"low\":");
-		sprintf(buf, "%.1f", profile->inittemp_lo);
+		payload = xstrcat(payload, (char *)",\"steptime\":");
+		sprintf(buf, "%d", pstep->steptime);
+		payload = xstrcat(payload, buf);
+		payload = xstrcat(payload, (char *)",\"target\":{\"low\":");
+		sprintf(buf, "%.1f", pstep->target_lo);
 		payload = xstrcat(payload, buf);
 		payload = xstrcat(payload, (char *)",\"high\":");
-		sprintf(buf, "%.1f", profile->inittemp_hi);
+		sprintf(buf, "%.1f", pstep->target_hi);
 		payload = xstrcat(payload, buf);
 		payload = xstrcat(payload, (char *)"},\"fridgemode\":");
-		sprintf(buf, "%d", profile->fridge_mode);
+		sprintf(buf, "%d", pstep->fridge_mode);
 		payload = xstrcat(payload, buf);
-		comma = false;
-		if (profile->steps) {
-		    payload = xstrcat(payload, (char *)",\"steps\":[");
-		    for (pstep = profile->steps; pstep; pstep = pstep->next) {
-			if (comma)
-			    payload = xstrcat(payload, (char *)",");
-			payload = xstrcat(payload, (char *)"{\"resttime\":");
-			sprintf(buf, "%d", pstep->resttime);
-			payload = xstrcat(payload, buf);
-			payload = xstrcat(payload, (char *)",\"steptime\":");
-			sprintf(buf, "%d", pstep->steptime);
-			payload = xstrcat(payload, buf);
-			payload = xstrcat(payload, (char *)",\"target\":{\"low\":");
-			sprintf(buf, "%.1f", pstep->target_lo);
-			payload = xstrcat(payload, buf);
-			payload = xstrcat(payload, (char *)",\"high\":");
-			sprintf(buf, "%.1f", pstep->target_hi);
-			payload = xstrcat(payload, buf);
-			payload = xstrcat(payload, (char *)"},\"fridgemode\":");
-			sprintf(buf, "%d", pstep->fridge_mode);
-			payload = xstrcat(payload, buf);
-			payload = xstrcat(payload, (char *)"}");
-			comma = true;
-		    }
-		    payload = xstrcat(payload, (char *)"]");
-		} else {
-		    payload = xstrcat(payload, (char *)",\"steps\":null");
+		if (pstep->name) {
+		    payload = xstrcat(payload, (char *)",\"name\":\"");
+		    payload = xstrcat(payload, pstep->name);
+		    payload = xstrcat(payload, (char *)"\"");
 		}
 		payload = xstrcat(payload, (char *)"}");
-		break;
+		comma = true;
 	    }
+	    payload = xstrcat(payload, (char *)"]");
+	} else {
+	    payload = xstrcat(payload, (char *)",\"steps\":null");
 	}
+	payload = xstrcat(payload, (char *)"}");
     } else {
 	payload = xstrcat(payload, (char *)",\"profile\":null");
     }

mercurial