thermferm/mqtt.c

changeset 569
9c69d43bfb06
parent 566
776a605befa5
child 570
1e0192b295b9
--- a/thermferm/mqtt.c	Mon Jan 07 13:23:17 2019 +0100
+++ b/thermferm/mqtt.c	Thu Jan 10 16:33:42 2019 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2016-2018
+ * Copyright (C) 2016-2019
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -21,6 +21,8 @@
  *****************************************************************************/
 
 #include "thermferm.h"
+#include "logger.h"
+#include "devices.h"
 #include "xutil.h"
 #include "mqtt.h"
 
@@ -159,8 +161,9 @@
 
 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message)
 {
-    char		*message_type;
-    struct json_object	*jobj, *metric, *val;
+    char		*message_type, *message_node, *message_alias;
+    units_list		*unit;
+    struct json_object	*jobj, *metric, *val, *setpoint;
     time_t		timestamp;
     int			timediff;
 
@@ -171,6 +174,8 @@
 	strtok(message->topic, "/");	// Ignore mbv1.0
 	strtok(NULL, "/");		// Ignore group_id
 	message_type = strtok(NULL, "/");
+	message_node = strtok(NULL, "/\0");
+	message_alias = strtok(NULL, "\0");
 
 	jobj = json_tokener_parse(message->payload);
 	if (json_object_object_get_ex(jobj, "timestamp", &val)) {
@@ -200,6 +205,166 @@
 			    return;
 			}
 		    }
+		    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) {
+						syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", message_alias, UNITSTAGE[i]);
+						unit->mqtt_flag |= MQTT_FLAG_DATA;
+				    	    	unit->stage = i;
+					    }
+					    break;
+					}
+				    }
+			    	}
+				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) {
+					    if (unit->mode != i) {
+						syslog(LOG_NOTICE, "DCMD change fermenter %s: mode to %s", message_alias, UNITMODE[i]);
+						unit->mqtt_flag |= MQTT_FLAG_DATA;
+						/* Initialize log if the unit is turned on */
+						if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) {
+						    initlog(unit->product_code, unit->product_name);
+						    unit->mqtt_flag |= MQTT_FLAG_BIRTH;
+						} else if ((unit->mode != UNITMODE_OFF) && (i == UNITMODE_OFF)) {
+						    unit->mqtt_flag |= MQTT_FLAG_DEATH;
+						}
+						syslog(LOG_NOTICE, "Fermenter unit %s mode %s to %s", unit->uuid, UNITMODE[unit->mode], UNITMODE[i]);
+						unit->mode = i;
+						/* Allways turn everything off after a mode change */
+						unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0;
+						unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE;
+						unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = 0;
+						unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
+						device_out(unit->heater_address, unit->heater_state);
+						device_out(unit->cooler_address, unit->cooler_state);
+						device_out(unit->fan_address, unit->fan_state);
+						device_out(unit->light_address, unit->light_state);
+						if (unit->mode == UNITMODE_PROFILE) {
+						    /*
+						     * Set a sane default until it will be overruled by the
+						     * main processing loop.
+						     */
+						    unit->prof_target_lo = unit->prof_target_hi = 20.0;
+						    unit->prof_fridge_mode = 0;
+						    if (unit->profile) {
+							unit->mqtt_flag |= MQTT_FLAG_DATA;
+						    }
+						}
+					    }
+					    break;
+					}
+				    }
+				}
+				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.
+					 */
+				        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)) {
+					    unit->PID_cool->SetP = json_object_get_double(val);
+				    	}
+					if (unit->mode == UNITMODE_FRIDGE) {
+					    unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2);
+					} 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) {
+					    unit->heater_state = json_object_get_int(val);
+					    if (unit->heater_state)	// Safety
+						    unit->cooler_state = 0;
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: heater_state to %d", message_alias, unit->heater_state);
+					}
+				    }
+				}
+				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) {
+					    unit->cooler_state = json_object_get_int(val);
+					    if (unit->cooler_state)
+					    	unit->heater_state = 0;
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: cooler_state to %d", message_alias, unit->cooler_state);
+					}
+				    }
+				}
+				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) {
+					    unit->fan_state = json_object_get_int(val);
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: fan_state to %d", message_alias, unit->fan_state);
+					}
+				    }
+				}
+				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) {
+					    unit->light_state = json_object_get_int(val);
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: light_state to %d", message_alias, unit->light_state);
+					}
+				    }
+				}
+				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)) {
+					    free(unit->product_code);
+					    unit->product_code = xstrcpy((char *)json_object_get_string(val));
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: product_code to `%s'", message_alias, unit->product_code);
+					}
+				    }
+				    if (json_object_object_get_ex(setpoint, "name", &val)) {
+					if (strcmp((char *)json_object_get_string(val), unit->product_name)) {
+					    free(unit->product_name);
+					    unit->product_name = xstrcpy((char *)json_object_get_string(val));
+					    unit->mqtt_flag |= MQTT_FLAG_DATA;
+					    syslog(LOG_NOTICE, "DCMD change fermenter %s: product_name to `%s'", message_alias, unit->product_name);
+					}
+				    }
+				}
+			    }
+			    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 {
+				    publishDData(unit);
+			    	}
+				if (unit->mqtt_flag & MQTT_FLAG_DEATH) {
+				    publishDDeath(unit);
+			    	}
+			    	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;

mercurial