Versie 0.8.5. Implementatie product code en product naam. Implementatie DLOG MQTT berichten. Verminderde server rotocol debug berichten.

Tue, 31 Jul 2018 16:42:11 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 31 Jul 2018 16:42:11 +0200
changeset 554
ab9f22ab57b5
parent 553
4091d4fe217f
child 555
c6f04bfcec2c

Versie 0.8.5. Implementatie product code en product naam. Implementatie DLOG MQTT berichten. Verminderde server rotocol debug berichten.

configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
thermferm/logger.c file | annotate | diff | comparison | revisions
thermferm/logger.h file | annotate | diff | comparison | revisions
thermferm/mqtt.c file | annotate | diff | comparison | revisions
thermferm/mqtt.h file | annotate | diff | comparison | revisions
thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/thermferm.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
www-thermferm/liveview.php file | annotate | diff | comparison | revisions
www-thermferm/units.php file | annotate | diff | comparison | revisions
--- a/configure	Wed Jul 25 20:08:13 2018 +0200
+++ b/configure	Tue Jul 31 16:42:11 2018 +0200
@@ -2035,7 +2035,7 @@
 
 
 PACKAGE="mbsePi-apps"
-VERSION="0.8.4"
+VERSION="0.8.5"
 COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2018"
 
--- a/configure.ac	Wed Jul 25 20:08:13 2018 +0200
+++ b/configure.ac	Tue Jul 31 16:42:11 2018 +0200
@@ -8,7 +8,7 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="mbsePi-apps"
-VERSION="0.8.4"
+VERSION="0.8.5"
 COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2018"
 AC_SUBST(PACKAGE)
--- a/thermferm/logger.c	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/logger.c	Tue Jul 31 16:42:11 2018 +0200
@@ -26,12 +26,14 @@
 #include "xutil.h"
 
 
-void initlog(char *unit)
+void initlog(char *code, char *name)
 {
     char	buf[128], *filename;
 
     snprintf(buf, 127, "Mode,Air,Beer,Target_L,S_Heater,S_Cooler,S_Fan,S_Door,U_Heater,U_Cooler,U_Fan,Room,Target_H,Chiller");
-    filename = xstrcpy(unit);
+    filename = xstrcpy(code);
+    filename = xstrcat(filename, (char *)" ");
+    filename = xstrcat(filename, name);
     filename = xstrcat(filename, (char *)".log");
     logger(filename, buf);
     free(filename);
--- a/thermferm/logger.h	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/logger.h	Tue Jul 31 16:42:11 2018 +0200
@@ -3,7 +3,7 @@
 
 
 void logger(char *, char *);
-void initlog(char *);
+void initlog(char *, char *);
 
 
 #endif
--- a/thermferm/mqtt.c	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/mqtt.c	Tue Jul 31 16:42:11 2018 +0200
@@ -300,14 +300,34 @@
 
     /*
      * Product (beer) loaded information.
-     * TODO: extend with uuid and product code.
      */
-    if (unit->name || strlen(unit->name)) {
-    	payload = xstrcat(payload, (char *)"\"product\":{\"code\":null,\"name\":\"");
-    	payload = xstrcat(payload, unit->name);
-    	payload = xstrcat(payload, (char *)"\"}");
-    } else {
-	payload = xstrcat(payload, (char *)"\"product\":null");
+    if ((unit->product_name && strlen(unit->product_name)) || 
+	(unit->product_code && strlen(unit->product_code)) || 
+	(unit->product_uuid && strlen(unit->product_uuid))) { 
+	comma = false;
+    	payload = xstrcat(payload, (char *)"\"product\":{");
+	if (unit->product_uuid && strlen(unit->product_uuid)) {
+	    payload = xstrcat(payload, (char *)"\"uuid\":\"");
+	    payload = xstrcat(payload, unit->product_uuid);
+	    payload = xstrcat(payload, (char *)"\"");
+	    comma = true;
+	}
+	if (unit->product_code && strlen(unit->product_code)) {
+	    if (comma)
+		payload = xstrcat(payload, (char *)",");
+	    payload = xstrcat(payload, (char *)"\"code\":\"");
+	    payload = xstrcat(payload, unit->product_code);
+	    payload = xstrcat(payload, (char *)"\"");
+	    comma = true;
+	}
+	if (unit->product_name && strlen(unit->product_name)) {
+	    if (comma)
+		payload = xstrcat(payload, (char *)",");
+	    payload = xstrcat(payload, (char *)"\"name\":\"");
+	    payload = xstrcat(payload, unit->product_name);
+	    payload = xstrcat(payload, (char *)"\"");
+	}
+    	payload = xstrcat(payload, (char *)"}");
     }
 
     /*
@@ -626,6 +646,135 @@
 
 
 
+void publishDLog(units_list *unit)
+{
+    char        buf[32], *payload = NULL, *topic = NULL;
+    bool	comma = false;
+
+    if (mqtt_use) {
+	payload = payload_header();
+	payload = xstrcat(payload, (char *)"{");
+
+	if ((unit->product_name && strlen(unit->product_name)) || 
+	    (unit->product_code && strlen(unit->product_code)) || 
+	    (unit->product_uuid && strlen(unit->product_uuid))) {
+	    comma = false;
+	    payload = xstrcat(payload, (char *)"\"product\":{");
+	    if (unit->product_uuid && strlen(unit->product_uuid)) {
+		payload = xstrcat(payload, (char *)"\"uuid\":\"");
+		payload = xstrcat(payload, unit->product_uuid);
+		payload = xstrcat(payload, (char *)"\"");
+		comma = true;
+	    }
+	    if (unit->product_code && strlen(unit->product_code)) {
+		if (comma)
+		    payload = xstrcat(payload, (char *)",");
+		payload = xstrcat(payload, (char *)"\"code\":\"");
+		payload = xstrcat(payload, unit->product_code);
+		payload = xstrcat(payload, (char *)"\"");
+		comma = true;
+	    }
+	    if (unit->product_name && strlen(unit->product_name)) {
+		if (comma)
+		    payload = xstrcat(payload, (char *)",");
+		payload = xstrcat(payload, (char *)"\"name\":\"");
+		payload = xstrcat(payload, unit->product_name);
+		payload = xstrcat(payload, (char *)"\"");
+	    }
+	    payload = xstrcat(payload, (char *)"}");
+	    comma = true;
+	}
+
+	if (comma)
+	    payload = xstrcat(payload, (char *)",");
+	payload = xstrcat(payload, (char *)"\"stage\":\"PRIMARY\",\"mode\":\"");
+	payload = xstrcat(payload, (char *)UNITMODE[unit->mode]);
+	payload = xstrcat(payload, (char *)"\",\"temperature\":{");
+	comma = false;
+	if (unit->air_address) {
+	    payload = xstrcat(payload, (char *)"\"air\":");
+	    sprintf(buf, "%.3f", unit->air_temperature / 1000.0);
+	    payload = xstrcat(payload, buf);
+	    comma = true;
+	}
+	if (unit->beer_address) {
+	    if (comma)
+		payload = xstrcat(payload, (char *)",");
+	    payload = xstrcat(payload, (char *)"\"beer\":");
+	    sprintf(buf, "%.3f", unit->beer_temperature / 1000.0);
+	    payload = xstrcat(payload, buf);
+	    comma = true;
+	}
+	if (unit->chiller_address) {
+	    if (comma)
+		payload = xstrcat(payload, (char *)",");
+	    payload = xstrcat(payload, (char *)"\"chiller\":");
+	    sprintf(buf, "%.3f", unit->chiller_temperature / 1000.0);
+	    payload = xstrcat(payload, buf);
+	    comma = true;
+	}
+	if (Config.temp_address) {
+	    if (comma)
+		payload = xstrcat(payload, (char *)",");
+	    payload = xstrcat(payload, (char *)"\"room\":");
+	    sprintf(buf, "%.1f", Config.temp_value / 1000.0);
+	    payload = xstrcat(payload, buf);
+	}
+	payload = xstrcat(payload, (char *)"},\"setpoint\":{\"low\":");
+	sprintf(buf, "%.1f", unit->PID_heat->SetP);
+	payload = xstrcat(payload, buf);
+	payload = xstrcat(payload, (char *)",\"high\":");
+	sprintf(buf, "%.1f", unit->PID_cool->SetP);
+	payload = xstrcat(payload, buf);
+	payload = xstrcat(payload, (char *)"}");
+	if (unit->heater_address) {
+	    payload = xstrcat(payload, (char *)",\"heater\":{\"power\":");
+	    sprintf(buf, "%d", unit->heater_state);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)",\"usage\":");
+	    sprintf(buf, "%d", unit->heater_usage);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)"}");
+	}
+	if (unit->cooler_address) {
+	    payload = xstrcat(payload, (char *)",\"cooler\":{\"power\":");
+	    sprintf(buf, "%d", unit->cooler_state);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)",\"usage\":");
+	    sprintf(buf, "%d", unit->cooler_usage);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)"}");
+	}
+	if (unit->fan_address) {
+	    payload = xstrcat(payload, (char *)",\"fan\":{\"power\":");
+	    sprintf(buf, "%d", unit->fan_state);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)",\"usage\":");
+	    sprintf(buf, "%d", unit->fan_usage);
+	    payload = xstrcat(payload, buf);
+	    payload = xstrcat(payload, (char *)"}");
+	}
+	// sg
+	if (unit->event_msg) {
+	    payload = xstrcat(payload, (char *)",\"event\":\"");
+	    payload = xstrcat(payload, unit->event_msg);
+	    payload = xstrcat(payload, (char *)"\"");
+	}
+	payload = xstrcat(payload, (char *)"}}");
+
+	topic = xstrcat(topic_base((char *)"DLOG"), (char *)"/");
+	topic = xstrcat(topic, unit->alias);
+	publisher(mosq, topic, payload, true);
+printf("%s\n", payload);
+	free(payload);
+	payload = NULL;
+	free(topic);
+	topic = NULL;
+    }
+}
+
+
+
 void publishNData(bool birth, int flag)
 {
     char		*payload = NULL, sidx[10], buf[64];
--- a/thermferm/mqtt.h	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/mqtt.h	Tue Jul 31 16:42:11 2018 +0200
@@ -41,6 +41,12 @@
 void publishDDeath(units_list *unit);
 
 /**
+ * @brief Publish log data.
+ * @param unit Unit data structure.
+ */
+void publishDLog(units_list *unit);
+
+/**
  * @brief Publish Node data or birth message.
  * @param birth If true send a birh message, else a regular data update.
  * @param flag Bit flag to enable control messages.
--- a/thermferm/rdconfig.c	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/rdconfig.c	Tue Jul 31 16:42:11 2018 +0200
@@ -82,8 +82,12 @@
     for (tmp2 = Config.units; tmp2; tmp2 = tmp2->next) {
 	if (tmp2->uuid)
 	    free(tmp2->uuid);
-	if (tmp2->name)
-	    free(tmp2->name);
+	if (tmp2->product_uuid)
+	    free(tmp2->product_uuid);
+	if (tmp2->product_code)
+	    free(tmp2->product_code);
+	if (tmp2->product_name)
+	    free(tmp2->product_name);
 	if (tmp2->air_address)
 	    free(tmp2->air_address);
 	if (tmp2->beer_address)
@@ -356,7 +360,15 @@
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
-	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", tmp3->name)) < 0) {
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRODUCT_UUID", "%s", tmp3->product_uuid)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRODUCT_CODE", "%s", tmp3->product_code)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRODUCT_NAME", "%s", tmp3->product_name)) < 0) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
@@ -1116,7 +1128,8 @@
     unit = (units_list *)malloc(sizeof(units_list));
     unit->next = NULL;
     unit->version = 1;
-    unit->uuid = unit->name = unit->alias = unit->air_address = unit->beer_address = unit->chiller_address = unit->heater_address = \
+    unit->uuid = unit->product_uuid = unit->product_code = unit->product_name = unit->event_msg = \
+		 unit->alias = unit->air_address = unit->beer_address = unit->chiller_address = unit->heater_address = \
 		 unit->cooler_address = unit->fan_address = unit->door_address = \
 		 unit->light_address = unit->psu_address = unit->profile = NULL;
     unit->volume = unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
@@ -1154,7 +1167,26 @@
 	    unit->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
-	    unit->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    /*
+	     * Upgrade to product code and name
+	     */
+	    char  *oldname =  (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (strstr(oldname, (char *)" ")) {
+		unit->product_code = xstrcpy(strtok(oldname, " "));
+		unit->product_name = xstrcpy(strtok(NULL, "\0"));
+	    } else {
+		unit->product_code = xstrcpy((char *)"000000");
+		unit->product_name = xstrcpy(oldname);
+	    }
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRODUCT_UUID"))) {
+	    unit->product_uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRODUCT_CODE"))) {
+	    unit->product_code = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRODUCT_NAME"))) {
+	    unit->product_name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"ALIAS"))) {
 	    unit->alias = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
--- a/thermferm/server.c	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/server.c	Tue Jul 31 16:42:11 2018 +0200
@@ -92,10 +92,10 @@
     vsnprintf(out, SS_BUFSIZE-1, format, va_ptr);
     va_end(va_ptr);
 
-    if (debug) {
-	syslog(LOG_NOTICE, "send: \"%s\"", out);
-	fprintf(stdout, "send: \"%s\"\n", out);
-    }
+//    if (debug) {
+//	syslog(LOG_NOTICE, "send: \"%s\"", out);
+//	fprintf(stdout, "send: \"%s\"\n", out);
+//    }
 
     if (send(s, out, strlen(out), 0) != strlen(out)) {
 	syslog(LOG_NOTICE, "srv_send failed");
@@ -148,10 +148,10 @@
 	}
     } 
 
-    if (debug) {
-	syslog(LOG_NOTICE, "recv: %d `%s'", bytesloaded, buffer);
-	fprintf(stdout, "recv: %d `%s'\n", bytesloaded, buffer);
-    }
+//    if (debug) {
+//	syslog(LOG_NOTICE, "recv: %d `%s'", bytesloaded, buffer);
+//	fprintf(stdout, "recv: %d `%s'\n", bytesloaded, buffer);
+//    }
     return bytesloaded;
 }
 
@@ -371,7 +371,9 @@
 		    found = 0;
 		    for (unit = Config.units; unit; unit = unit->next) {
 			if (unit->mode != UNITMODE_OFF) {
-			    logname = xstrcpy(unit->name);
+			    logname = xstrcpy(unit->product_code);
+			    logname = xstrcat(logname, (char *)" ");
+			    logname = xstrcat(logname, unit->product_name);
 			    logname = xstrcat(logname, (char *)".log");
 			    if (! strcmp(result->d_name, logname))
 				found = 1;
@@ -1190,7 +1192,7 @@
 	 */
 	srv_send((char *)"212 Fermenter list follows:");
 	for (unit = Config.units; unit; unit = unit->next) {
-	    srv_send((char *)"%s,%s,%s", unit->uuid, unit->name, UNITMODE[unit->mode]);
+	    srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
 	}
 	srv_send((char *)".");
 	return 0;
@@ -1810,8 +1812,15 @@
 		Config.units = current->next;
 		free(current->uuid);
 		current->uuid = NULL;
-		free(current->name);
-		current->name = NULL;
+		if (current->product_uuid)
+		    free(current->product_uuid);
+		current->product_uuid = NULL;
+		if (current->product_code)
+		    free(current->product_code);
+		current->product_code = NULL;
+		if (current->product_name)
+		    free(current->product_name);
+		current->product_name = NULL;
 		if (current->air_address)
 		    free(current->air_address);
 		current->air_address = NULL;
@@ -1853,8 +1862,15 @@
 	    } else {
 		free(current->uuid);
 		current->uuid = NULL;
-		free(current->name);
-		current->name = NULL;
+		if (current->product_uuid)
+		    free(current->product_uuid);
+		current->product_uuid = NULL;
+		if (current->product_code)
+		    free(current->product_code);
+		current->product_code = NULL;
+		if (current->product_name)
+		    free(current->product_name);
+		current->product_name = NULL;
 		if (current->air_address)
 		    free(current->air_address);
 		current->air_address = NULL;
@@ -1945,7 +1961,7 @@
     if ((strcmp(opt, (char *)"LIST") == 0) && (param == NULL)) {
 	srv_send((char *)"212 Fermenter list follows:");
 	for (unit = Config.units; unit; unit = unit->next) {
-	    srv_send((char *)"%s,%s,%s", unit->uuid, unit->name, UNITMODE[unit->mode]);
+	    srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
 	}
 	srv_send((char *)".");
 	return 0;
@@ -1967,7 +1983,9 @@
 	unit->uuid = malloc(37);
 	uuid_generate(uu);
 	uuid_unparse(uu, unit->uuid);
-	unit->name = xstrcpy(param);
+	unit->product_uuid = NULL;
+	unit->product_code = xstrcpy((char *)"FAKE0000");
+	unit->product_name = xstrcpy(param);
 	unit->alias = xstrcpy(an);
 	unit->air_address = unit->beer_address = unit->chiller_address = unit->heater_address = unit->cooler_address = \
 			    unit->fan_address = unit->door_address = unit->light_address = \
@@ -2050,9 +2068,10 @@
 	for (unit = Config.units; unit; unit = unit->next) {
 	    if (strcmp(param, unit->uuid) == 0) {
 		srv_send((char *)"213 Unit listing follows:");
-		srv_send((char *)"NAME,%s", unit->name);
 		srv_send((char *)"UUID,%s", unit->uuid);
 		srv_send((char *)"ALIAS,%s", unit->alias);
+		srv_send((char *)"PRODUCT_NAME,%s", unit->product_name);
+		srv_send((char *)"PRODUCT_CODE,%s", unit->product_code);
 		srv_send((char *)"MODE,%s", UNITMODE[unit->mode]);
 		srv_send((char *)"VOLUME,%2f", unit->volume);
 		srv_send((char *)"AIR_ADDRESS,%s", unit->air_address);
@@ -2170,14 +2189,24 @@
 			     * but may also sent everything. Simply ignore things we
 			     * don't understand.
 			     */
-			    if (val && (strcmp(kwd, (char *)"NAME") == 0)) {
-				if (unit->name) {
-				    if (strcmp(unit->name, val)) {
-					syslog(LOG_NOTICE, "Fermenter unit %s name `%s' to `%s'", unit->uuid, unit->name, val);
+			    if (val && (strcmp(kwd, (char *)"PRODUCT_CODE") == 0)) {
+				if (unit->product_code) {
+				    if (strcmp(unit->product_code, val)) {
+					syslog(LOG_NOTICE, "Fermenter unit %s name `%s' to `%s'", unit->uuid, unit->product_code, val);
 				    }
-				    free(unit->name);
+				    free(unit->product_code);
 				}
-				unit->name = xstrcpy(val);
+				unit->product_code = xstrcpy(val);
+				unit->mqtt_flag |= MQTT_FLAG_DATA;
+
+			    } else if (val && (strcmp(kwd, (char *)"PRODUCT_NAME") == 0)) {
+				if (unit->product_name) {
+				    if (strcmp(unit->product_name, val)) {
+					syslog(LOG_NOTICE, "Fermenter unit %s name `%s' to `%s'", unit->uuid, unit->product_name, val);
+				    }
+				    free(unit->product_name);
+				}
+				unit->product_name = xstrcpy(val);
 				unit->mqtt_flag |= MQTT_FLAG_DATA;
 
 			    } else if (val && (strcmp(kwd, (char *)"VOLUME") == 0)) {
@@ -2441,7 +2470,7 @@
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
 					/* Initialize log if the unit is turned on */
 					if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) {
-					    initlog(unit->name);
+					    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;
@@ -2651,6 +2680,7 @@
 				if (unit->mqtt_flag & MQTT_FLAG_DEATH) {
 				    publishDDeath(unit);
 				}
+			    	unit->mqtt_flag |= MQTT_FLAG_DLOG;	// Something to log
 			    }
 #endif
 			}
--- a/thermferm/thermferm.c	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/thermferm.c	Tue Jul 31 16:42:11 2018 +0200
@@ -188,7 +188,7 @@
 #endif
 				slcdPuts(slcdHandle, "Choose unit:");
 				slcdPosition(slcdHandle, 0, 1);
-				slcdPuts(slcdHandle, current_unit->name);
+				slcdPuts(slcdHandle, current_unit->alias);
 				break;
 
 	case MENU_MODE_OFF:	show_mode();
@@ -394,7 +394,7 @@
 {
     current_unit->mqtt_flag |= MQTT_FLAG_DATA;
     if ((current_unit->mode == UNITMODE_OFF) && (mode != UNITMODE_OFF)) {
-	initlog(current_unit->name);
+	initlog(current_unit->product_code, current_unit->product_name);
 	current_unit->mqtt_flag |= MQTT_FLAG_BIRTH;
     } else if ((current_unit->mode != UNITMODE_OFF) && (mode == UNITMODE_OFF)) {
 	current_unit->mqtt_flag |= MQTT_FLAG_DEATH;
@@ -1082,29 +1082,40 @@
 	unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
 	if (unit->mode == UNITMODE_PROFILE) {
 	    if (!unit->profile)
-		syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name);
+		syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->alias);
 	    else {
-	    	syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
+	    	syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->alias, PROFSTATE[unit->prof_state]);
 	    }
 	} else if (unit->mode == UNITMODE_BEER) {
-	    syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set);
+	    syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->alias, unit->beer_set);
 	} else if (unit->mode == UNITMODE_FRIDGE) {
-	    syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
+	    syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->alias, unit->fridge_set);
 	} else if (unit->mode == UNITMODE_NONE) {
-	    syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name);
+	    syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->alias);
 	} else {
-	    syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name);
+	    syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->alias);
 	}
 
 	/*
 	 * Initialize logfile
 	 */
 	if (unit->mode != UNITMODE_OFF) {
-	    initlog(unit->name);
+	    initlog(unit->product_code, unit->product_name);
 	}
     }
+    printf("Units started\n");
 #ifdef HAVE_MOSQUITTO_H
     publishDBirthAll();
+    printf("Birth all done\n");
+
+    for (unit = Config.units; unit; unit = unit->next) {
+	if (unit->mode != UNITMODE_OFF) {
+    	    unit->event_msg = xstrcpy((char *)"Startup");
+            publishDLog(unit);
+	    free(unit->event_msg);
+	    unit->event_msg = NULL;
+	}
+    }
 #endif
 
 #ifdef HAVE_WIRINGPI_H
@@ -1331,7 +1342,7 @@
 		    if (rc == DEVPRESENT_YES) {
 			if (temp) {
 			    if (unit->door_state == 0) {
-			    	syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name);
+			    	syslog(LOG_NOTICE, "Unit `%s' door closed", unit->alias);
 			    	unit->door_state = 1;
 #ifdef HAVE_MOSQUITTO_H
 				pub_domoticz_output(unit->door_idx, unit->door_state);
@@ -1340,7 +1351,7 @@
 			    }
 			} else {
 			    if (unit->door_state) {
-			    	syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name);
+			    	syslog(LOG_NOTICE, "Unit `%s' door opened", unit->alias);
 			    	unit->door_state = 0;
 #ifdef HAVE_MOSQUITTO_H
 				pub_domoticz_output(unit->door_idx, unit->door_state);
@@ -1369,7 +1380,7 @@
 		    if (rc == DEVPRESENT_YES) {
 			if (temp) {
 			    if (unit->psu_state == 0) {
-				syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->name);
+				syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->alias);
 				unit->psu_state = 1;
 #ifdef HAVE_MOSQUITTO_H
 				pub_domoticz_output(unit->psu_idx, unit->psu_state);
@@ -1378,7 +1389,7 @@
 			    }
 			} else {
 			    if (unit->psu_state) {
-				syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->name);
+				syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->alias);
 				unit->psu_state = 0;
 #ifdef HAVE_MOSQUITTO_H
 				pub_domoticz_output(unit->psu_idx, unit->psu_state);
@@ -1615,7 +1626,7 @@
 			    unit->light_wait--;
 			} else {
 			    unit->light_state = 0;
-			    syslog(LOG_NOTICE, "Unit `%s' lights On => Off", unit->name);
+			    syslog(LOG_NOTICE, "Unit `%s' lights On => Off", unit->alias);
 			    unit->mqtt_flag |= MQTT_FLAG_DATA;
 			}
 		    }
@@ -1623,7 +1634,7 @@
 			unit->light_wait = unit->light_delay;   /* No delay to turn lights on   */
 			unit->light_state = 1;
 			unit->mqtt_flag |= MQTT_FLAG_DATA;
-			syslog(LOG_NOTICE, "Unit `%s' lights Off => On", unit->name);
+			syslog(LOG_NOTICE, "Unit `%s' lights Off => On", unit->alias);
 		    }
 		    device_out(unit->light_address, unit->light_state);
 		}
@@ -1736,12 +1747,14 @@
 			    } else {
 				int	power = round(unit->PID_heat->OutP);
 				if (unit->heater_state != power) {
-				    syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power);
+				    syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->alias, unit->heater_state, power);
 				    unit->heater_state = power;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->heater_idx, unit->heater_state);
-				    if (unit->heater_address)
+				    if (unit->heater_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+					unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 				}
 			    }
@@ -1750,12 +1763,14 @@
 				unit->heater_wait--;
 			    } else {
 				if (unit->heater_state) {
-				    syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name);
+				    syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->alias);
 				    unit->heater_state = 0;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->heater_idx, unit->heater_state);
-				    if (unit->heater_address)
+				    if (unit->heater_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+					unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 				}
 			    }
@@ -1774,12 +1789,14 @@
 			    } else {
 				int	power = round(unit->PID_cool->OutP); 
 				if (unit->cooler_state != power) {
-				    syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power);
+				    syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->alias, unit->cooler_state, power);
 				    unit->cooler_state = power;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->cooler_idx, unit->cooler_state);
-				    if (unit->cooler_address)
+				    if (unit->cooler_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+				    	unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 				}
 			    }
@@ -1788,12 +1805,14 @@
 				unit->cooler_wait--;
 			    } else {
 				if (unit->cooler_state) {
-				    syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name);
+				    syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->alias);
 				    unit->cooler_state = 0;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->cooler_idx, unit->cooler_state);
-				    if (unit->cooler_address)
+				    if (unit->cooler_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+					unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 				}
 			    }
@@ -1819,12 +1838,14 @@
 			    	unit->fan_wait++;
 			    } else {
 			    	if (! unit->fan_state) {
-				    syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name);
+				    syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->alias);
 				    unit->fan_state = 100;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->fan_idx, unit->fan_state);
-				    if (unit->fan_address)
+				    if (unit->fan_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+					unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 			    	}
 			    }
@@ -1833,12 +1854,14 @@
 				unit->fan_wait--;
 			    } else {
 			    	if (unit->fan_state) {
-				    syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name);
+				    syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->alias);
 			    	    unit->fan_state = 0;
 #ifdef HAVE_MOSQUITTO_H
 				    pub_domoticz_output(unit->fan_idx, unit->fan_state);
-				    if (unit->fan_address)
+				    if (unit->fan_address) {
 					unit->mqtt_flag |= MQTT_FLAG_DATA;
+					unit->mqtt_flag |= MQTT_FLAG_DLOG;
+				    }
 #endif
 				}
 			    }
@@ -1889,7 +1912,7 @@
 		 * Write 4 rows to the LCD to display the unit state
 		 */
 		lcd_buf_write(row++, "Unit %d: %s          ", LCDunit, UNITMODE[unit->mode]);
-		lcd_buf_write(row++, "%s                   ", unit->name);
+		lcd_buf_write(row++, "%s                   ", unit->product_name);
 		lcd_buf_write(row++, "%c%5.1f\2 A%6.2f\1    ", LCDstatC, LCDspH, LCDair);
 		lcd_buf_write(row++, "%c%5.1f\2 B%6.2f\1    ", LCDstatH, LCDspL, LCDbeer);
 #ifdef HAVE_WIRINGPI_H
@@ -1914,6 +1937,13 @@
 			publishDDeath(unit);
 			unit->mqtt_flag &= ~MQTT_FLAG_DEATH;
 		    }
+		    if (unit->mqtt_flag & MQTT_FLAG_DLOG) {
+			publishDLog(unit);
+			if (unit->event_msg)
+			    free(unit->event_msg);
+			unit->event_msg = NULL;
+			unit->mqtt_flag &= ~MQTT_FLAG_DLOG;
+		    }
 		}
 #endif
 
@@ -1921,7 +1951,7 @@
 		 * Handle changed alarms
 		 */
 		if (unit->alarm_flag != unit->alarm_last) {
-		    syslog(LOG_NOTICE, "Unit `%s' Alarm %d => %d", unit->name, unit->alarm_last, unit->alarm_flag);
+		    syslog(LOG_NOTICE, "Unit `%s' Alarm %d => %d", unit->alias, unit->alarm_last, unit->alarm_flag);
 		    unit->alarm_last = unit->alarm_flag;
 		}
 	    } /* for units */
@@ -1997,7 +2027,9 @@
 					unit->beer_temperature / 1000.0, 
 					target_lo, heater, cooler, fan, door, use_heater, use_cooler, use_fan, room_temp, target_hi,
 					unit->chiller_temperature / 1000.0);
-			filename = xstrcpy(unit->name);
+			filename = xstrcpy(unit->product_code);
+			filename = xstrcat(filename, (char *)" ");
+			filename = xstrcat(filename, unit->product_name);
 			filename = xstrcat(filename, (char *)".log");
 			logger(filename, buf);
 			free(filename);
@@ -2006,13 +2038,20 @@
 		}
 
 		minutes++;
+		if ((minutes % 5) == 0) {
+		    for (unit = Config.units; unit; unit = unit->next) {
+			if (unit->mode != UNITMODE_OFF) {
+			    unit->mqtt_flag |= MQTT_FLAG_DLOG;
+			}
+		    }
+		}
 		if (minutes == 60) {
 		    minutes = 0;
 		    /*
 		     * Log usage counters every hour
 		     */
 		    for (unit = Config.units; unit; unit = unit->next) {
-		    	syslog(LOG_NOTICE, "Unit `%s' usage heater=%d cooler=%d fan=%d", unit->name, unit->heater_usage, unit->cooler_usage, unit->fan_usage);
+		    	syslog(LOG_NOTICE, "Unit `%s' usage heater=%d cooler=%d fan=%d", unit->alias, unit->heater_usage, unit->cooler_usage, unit->fan_usage);
 		    }
 		}
 
@@ -2063,9 +2102,13 @@
 	    unit->mqtt_flag = MQTT_FLAG_DATA;
 	    publishDData(unit);
 	    publishDDeath(unit);
+	    unit->event_msg = xstrcpy((char *)"Shutdown");
+	    publishDLog(unit);
+	    free(unit->event_msg);
+	    unit->event_msg = NULL;
 	}
 #endif
-	syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]);
+	syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->alias, UNITMODE[unit->mode]);
     }
 
     usleep(100000);
--- a/thermferm/thermferm.h	Wed Jul 25 20:08:13 2018 +0200
+++ b/thermferm/thermferm.h	Tue Jul 31 16:42:11 2018 +0200
@@ -133,7 +133,9 @@
     struct _units_list	*next;
     int			version;		/* Record version		*/
     char		*uuid;			/* uid code			*/
-    char		*name;			/* friendly name		*/
+    char		*product_uuid;		/* Beer product uuid		*/
+    char		*product_code;		/* Beer product code		*/
+    char		*product_name;		/* Beer product name		*/
     char		*alias;			/* alias name 'unit1'		*/
     float		volume;			/* Volume of this unit		*/
     char		*air_address;		/* DS18B20 address		*/
@@ -197,6 +199,7 @@
     pid_var		*PID_cool;		/* PID cooler			*/
     pid_var		*PID_heat;		/* PID heater			*/
     int			mqtt_flag;		/* MQTT print values flag	*/
+    char		*event_msg;		/* Event message to log		*/
     int			alarm_flag;		/* Alarm flag			*/
     int			alarm_last;		/* Last alarm state		*/
 } units_list;
@@ -210,6 +213,7 @@
 #define	MQTT_FLAG_DATA		0x0001		/* Show updated data values	*/
 #define	MQTT_FLAG_BIRTH		0x0002		/* Show birth instead of data	*/
 #define MQTT_FLAG_DEATH		0x0004		/* Show death of a unit		*/
+#define	MQTT_FLAG_DLOG		0x0008		/* Send DLOG message		*/
 
 
 
--- a/www-thermferm/liveview.php	Wed Jul 25 20:08:13 2018 +0200
+++ b/www-thermferm/liveview.php	Tue Jul 31 16:42:11 2018 +0200
@@ -1,6 +1,6 @@
 <?php
 /*****************************************************************************
- * Copyright (C) 2014-2017
+ * Copyright (C) 2014-2018
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -26,11 +26,11 @@
 
 
 
-function showunit($unit, $unr, $name)
+function showunit($unit, $unr, $alias)
 {
     global $my_style;
 
-    $outstr = '    <!--  showunit(' . $unit . ', ' . $unr . ', ' . $name . ')  -->' . PHP_EOL;
+    $outstr = '    <!--  showunit(' . $unit . ', ' . $unr . ', ' . $alias . ')  -->' . PHP_EOL;
     $air_state = $beer_state = $chiller_state = 1;
     $answer = send_cmd("UNIT GET ".$unit);
     $arr = explode("\r\n", $answer);
@@ -43,6 +43,8 @@
 	$beer_temperature = "NA";
 	$chiller_temperature = "NA";
 	$profile = "";
+	$producr_code = "";
+	$product_name = "";
 	$prof_state = "OFF";
 	$power_led = $alarm_led = $cooler_led = $heater_led = $fan_led = "off";
 	$heater = $cooler = $fan = "no";
@@ -55,6 +57,12 @@
 		if (strcmp($mode, "OFF"))
 		    $power_led = "on";
 	    }
+	    if (strcmp($vals[0], "PRODUCT_CODE") == 0) {
+	    	$product_code = $vals[1];
+	    }
+	    if (strcmp($vals[0], "PRODUCT_NAME") == 0) {
+		$product_name = $vals[1];
+	    }
 	    if (strcmp($vals[0], "AIR_STATE") == 0) {
 		$air_state = $vals[1];
 	    }
@@ -111,6 +119,7 @@
 	    }
 	}
 
+	$logname = $product_code . " " . $product_name;
 	$outstr .= '    <script type="text/javascript">'.PHP_EOL;
 	$outstr .= '     $(document).ready(function () {'.PHP_EOL;
 
@@ -411,7 +420,7 @@
 	$outstr .= '       <input type="submit" id="maintenance" value="Graph" />'.PHP_EOL;
 	$outstr .= '       <input type="hidden" name="action" value="view">'.PHP_EOL;
 	$outstr .= '       <input type="hidden" name="return" value="index">'.PHP_EOL;
-	$outstr .= '       <input type="hidden" name="name" value="'.urlencode($name).'">'.PHP_EOL;
+	$outstr .= '       <input type="hidden" name="name" value="'.urlencode($logname).'">'.PHP_EOL;
 	$outstr .= '      </form>'.PHP_EOL;
  	$outstr .= '     </div>'.PHP_EOL;
 	$outstr .= '     </div> <!-- fermentor_panel_buttons -->'.PHP_EOL;
--- a/www-thermferm/units.php	Wed Jul 25 20:08:13 2018 +0200
+++ b/www-thermferm/units.php	Tue Jul 31 16:42:11 2018 +0200
@@ -1,6 +1,6 @@
 <?php
 /*****************************************************************************
- * Copyright (C) 2014-2017
+ * Copyright (C) 2014-2018
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -56,16 +56,16 @@
 /*
  * Unit add
  *
- * @param string $_POST['Name'] The rpofile name
+ * @param string $_POST['Name'] The product name
  */
 function unit_add() {
 
     if ($_POST['key'] == 'Add') {
-	send_cmd("UNIT ADD ".$_POST['Name']);
+	send_cmd("UNIT ADD ".$_POST['ProductName']);
     }
 
     unset($_POST['UUID']);
-    unset($_POST['Name']);
+    unset($_POST['roductName']);
     unset($_POST['key']);
     unset($_POST['command']);
     load('units.php');
@@ -77,7 +77,6 @@
  * Unit update
  *
  * @param string $_POST['UUID'] The unit UUID
- * @param string $_POST['Name'] The unit name
  * @param string $_POST['key'] The button pressed.
  */
 function unit_update() {
@@ -90,7 +89,8 @@
 
     if ($_POST['key'] == 'Save') {
 	$cmd = array("UNIT PUT ".$_POST['UUID']);
-	$cmd[] = "NAME,".$_POST['Name'];
+	$cmd[] = "PRODUCT_CODE,".$_POST['ProductCode'];
+	$cmd[] = "PRODUCT_NAME,".$_POST['ProductName'];
 	$cmd[] = "VOLUME,".$_POST['Volume'];
 	$cmd[] = "AIR_ADDRESS,".$_POST['AirAddress'];
 	$cmd[] = "AIR_IDX,".$_POST['AirIdx'];
@@ -131,7 +131,8 @@
     }
 
     unset($_POST['UUID']);
-    unset($_POST['Name']);
+    unset($_POST['ProductName']);
+    unset($_POST['ProductCode']);
     unset($_POST['Volume']);
     unset($_POST['key']);
     unset($_POST['command']);
@@ -175,17 +176,16 @@
 
 
 /*
- * Test input of a modified or new profile.
+ * Test input of a modified or new fermentation unit.
  *
  * @param string $_POST['UUID'] Unique record UUID
- * @param string $_POST['Name'] Profile name
  * @param string $_POST['key'] Key choice, Save or Cancel
  * @param string $_POST['command'] Command used, 'add' or 'update'
  *
  * Return: 0 = Ok
  *         1 = Missing data
- *         2 = Name field too short
- *         3 = Name already in use
+ *  //       2 = Name field too short
+ *  //       3 = Name already in use
  *         4 = TempSetMax <= TempSetMin
  *         5 = TempSetMax < 25 or > 35
  *         6 = TempSetMin < -5 or > 15
@@ -201,8 +201,10 @@
 
     global $arr;
 
-    if (isset($_POST['UUID']) && isset($_POST['Name']) && isset($_POST['Volume']) && isset($_POST['AirAddress']) && isset($_POST['ChillerAddress']) &&
-	isset($_POST['BeerAddress']) && isset($_POST['HeaterAddress']) && isset($_POST['CoolerAddress']) && isset($_POST['LightAddress']) &&
+    if (isset($_POST['UUID']) && isset($_POST['ProductCode']) && isset($_POST['ProductName']) && isset($_POST['Volume']) && 
+	isset($_POST['AirAddress']) && isset($_POST['ChillerAddress']) &&
+	isset($_POST['BeerAddress']) && isset($_POST['HeaterAddress']) && 
+	isset($_POST['CoolerAddress']) && isset($_POST['LightAddress']) &&
 	isset($_POST['HeaterDelay']) && isset($_POST['CoolerDelay']) && isset($_POST['LightDelay']) && isset($_POST['PSUAddress']) &&
 	isset($_POST['FanAddress']) && isset($_POST['DoorAddress']) && isset($_POST['TempSetMin']) && isset($_POST['TempSetMax']) &&
 	isset($_POST['PIDC_pGain']) && isset($_POST['PIDC_iGain']) && isset($_POST['PIDC_dGain']) && isset($_POST['PIDC_idleRange']) &&
@@ -215,10 +217,10 @@
 	if ($_POST['key'] == 'Cancel')
 	    return 99;
 
-    	if (strlen($_POST['Name']) < 2)
-	    return 2;
+//    	if (strlen($_POST['Name']) < 2)
+//	    return 2;
 
-    	if (startsWith($arr[0], "212")) {
+/*    	if (startsWith($arr[0], "212")) {
 	    $j = 1;
 	    while (1) {
 	    	if (strcmp($arr[$j], ".") == 0)
@@ -229,7 +231,7 @@
 	    	}
 	    	$j++;
 	    }
-	}
+	} */
 
 	if ($_POST['TempSetMax'] <= $_POST['TempSetMin'])
 	    return 4;
@@ -361,18 +363,27 @@
 		break;
 	    $f = explode(",", $reply[$i]);
 
-	    if ($f[0] == "NAME") {
-    		$outstr .= '       <tr class="editor">'.PHP_EOL;
-    		$outstr .= '        <td class="editname">Unit Name</td>'.PHP_EOL;
-    		$outstr .= '        <td colspan="3" class="editfield"><input type="text" name="Name" size="50" value="'.$f[1].'"></td>'.PHP_EOL;
+	    if ($f[0] == "PRODUCT_CODE") {
+	    	$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">Product Code</td>'.PHP_EOL;
+		$outstr .= '        <td colspan="3" class="editfield"><input type="text" name="ProductCode" size="32" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
+	    if ($f[0] == "PRODUCT_NAME") {
+    		$outstr .= '       <tr class="editor">'.PHP_EOL;
+    		$outstr .= '        <td class="editname">Product Name</td>'.PHP_EOL;
+    		$outstr .= '        <td colspan="3" class="editfield"><input type="text" name="ProductName" size="50" value="'.$f[1].'"></td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
+
 	    if ($f[0] == "VOLUME") {
     		$outstr .= '       <tr class="editor">'.PHP_EOL;
     		$outstr .= '        <td class="editname">Unit Volume</td>'.PHP_EOL;
     		$outstr .= '        <td colspan="3" class="editfield"><input type="text" name="Volume" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "AIR_ADDRESS") {
     		$outstr .= '       <tr class="editor">'.PHP_EOL;
     		$outstr .= '        <td class="editname">Air Sensor Address</td>'.PHP_EOL;
@@ -392,14 +403,13 @@
 		    }
 		}
     		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "AIR_IDX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Air domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="AirIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "BEER_ADDRESS") {
                 $outstr .= '       <tr class="editor">'.PHP_EOL;
                 $outstr .= '        <td class="editname">Beer Sensor Address</td>'.PHP_EOL;
@@ -419,14 +429,13 @@
                     }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "BEER_IDX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Beer domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="BeerIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "CHILLER_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Chiller Sensor Address</td>'.PHP_EOL;
@@ -446,14 +455,13 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "CHILLER_IDX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Chiller domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="ChillerIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "HEATER_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Heater Switch Address</td>'.PHP_EOL;
@@ -473,50 +481,46 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "HEATER_DELAY") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Heater Switch Delay</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="HeaterDelay" size="5" value="'.$f[1].'"> seconds (0..720)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "HEATER_IDX") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Heater domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="HeaterIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDH_IMAX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Heat Maximum</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDH_iMax" size="6" value="'.$f[1].'"> % (1..100)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "PIDH_IDLERANGE") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Heater Idle Range</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDH_idleRange" size="6" value="'.$f[1].'"> &deg;C (Heater margin)</td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDH_PGAIN") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Heat pGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDH_pGain" size="6" value="'.$f[1].'"> Proportional</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "PIDH_IGAIN") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Heat iGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDH_iGain" size="6" value="'.$f[1].'"> Intergral</td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDH_DGAIN") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Heat dGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDH_dGain" size="6" value="'.$f[1].'"> Derivative</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "COOLER_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Cooler Switch Address</td>'.PHP_EOL;
@@ -536,50 +540,46 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "COOLER_DELAY") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Cooler Switch Delay</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="CoolerDelay" size="5" value="'.$f[1].'"> seconds (0..720)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "COOLER_IDX") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Cooler domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="CoolerIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDC_IMAX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Cool Maximum</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDC_iMax" size="6" value="'.$f[1].'"> % (1..100)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "PIDC_IDLERANGE") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Cooler Idle Range</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDC_idleRange" size="6" value="'.$f[1].'"> &deg;C (Cooler margin)</td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDC_PGAIN") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Cool pGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDC_pGain" size="6" value="'.$f[1].'"> Proportional</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "PIDC_IGAIN") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Cool iGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDC_iGain" size="6" value="'.$f[1].'"> Intergral</td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PIDC_DGAIN") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PID Cool dGain</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PIDC_dGain" size="6" value="'.$f[1].'"> Derivative</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "FAN_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Fan Switch Address</td>'.PHP_EOL;
@@ -599,14 +599,13 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "FAN_DELAY") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Fan Switch Delay</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="FanDelay" size="5" value="'.$f[1].'"> seconds (0..720)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "FAN_IDX") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Fan domoticz idx</td>'.PHP_EOL;
@@ -632,20 +631,21 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "LIGHT_DELAY") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Lights Delay</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="LightDelay" size="5" value="'.$f[1].'"> seconds (0..720)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "LIGHT_IDX") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Light domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td colspan="3" class="editfield"><input type="text" name="LightIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "DOOR_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Door Sensor Address</td>'.PHP_EOL;
@@ -665,17 +665,16 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;                        
-//		$outstr .= '       </tr>'.PHP_EOL;                                  
 	    }
 	    if ($f[0] == "DOOR_IDX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Door domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="DoorIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "PSU_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
-		$outstr .= '        <td class="editname">Power Supply Sensor Address</td>'.PHP_EOL;
+		$outstr .= '        <td class="editname">PSU Sensor Address</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><select name="PSUAddress">'.PHP_EOL;
 		$outstr .= '         <option value="">Not Assigned</option>'.PHP_EOL;
 		if (startsWith($devices[0], "212")) {
@@ -692,26 +691,24 @@
 		    }
 		}
 		$outstr .= '        </select></td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "PSU_IDX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">PSU domoticz idx</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="PSUIdx" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    if ($f[0] == "TEMP_SET_MIN") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Min. temp setting</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="TempSetMin" size="5" value="'.$f[1].'"> &deg;C</td>'.PHP_EOL;
-//		$outstr .= '       </tr>'.PHP_EOL;
 	    }
 	    if ($f[0] == "TEMP_SET_MAX") {
-//		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Max. temp setting</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><input type="text" name="TempSetMax" size="5" value="'.$f[1].'"> &deg;C</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+
 	    $i++;
 	}
     }
@@ -769,7 +766,7 @@
     $outstr .= '     <table class="setup">'.PHP_EOL;
     $outstr .= '      <tr class="trhead">'.PHP_EOL;
     $outstr .= '       <td class="setup" style="width: 300px;">UUID</td>'.PHP_EOL;
-    $outstr .= '       <td class="setup" style="width: 300px;">Name</td>'.PHP_EOL;
+    $outstr .= '       <td class="setup" style="width: 300px;">Alias</td>'.PHP_EOL;
     $outstr .= '       <td class="setup" style="width: 60px;">Mode</td>'.PHP_EOL;
     $outstr .= '       <td class="setup" style="width: 40px;">Edit</td>'.PHP_EOL;
     $outstr .= '      </tr>'.PHP_EOL;
@@ -802,9 +799,10 @@
     $outstr .= '      <table class="editor">'.PHP_EOL;
     $outstr .= '      <tr class="trhead"><td colspan="3">Add new unit</td></tr>'.PHP_EOL;
     $outstr .= '       <tr class="editor">'.PHP_EOL;
-    $outstr .= '        <td class="editname">Unit Name</td>'.PHP_EOL;
-    $outstr .= '        <td class="editfield"><input type="text" name="Name" size="50" value=""></td>'.PHP_EOL;
+    $outstr .= '        <td class="editname">Product Name</td>'.PHP_EOL;
+    $outstr .= '        <td class="editfield"><input type="text" name="ProductName" size="50" value=""></td>'.PHP_EOL;
     $outstr .= '        <td class="editsub"><input type="submit" value="Add" name="key"></td>'.PHP_EOL;
+    $outstr .= '<input type="hidden" value="FAKE000" name="ProductCode">';
     $outstr .= '<input type="hidden" value="0.0" name="Volume">';
     $outstr .= '<input type="hidden" value="" name="AirAddress">';
     $outstr .= '<input type="hidden" value="0" name="AirIdx">';

mercurial