Version 0.9.19a2. Dropped TEMPSTATE[] and only use DEVPRESENT[] to mark devices state. Adjusted webpages for this switch in responses. Adjusted MySQL mon_fermenters enum values too. Rename some global Config records to better reflect their real use.Added one-wire json records and websocket. Announce when some onewire device changes. Add UNITS JSON command without parameter. Dropped global tempFormat setting that was never used.

Mon, 22 Apr 2024 11:33:04 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 22 Apr 2024 11:33:04 +0200
changeset 693
3518c07737d8
parent 692
6d97eb820cc1
child 694
0f1ef5e6418e

Version 0.9.19a2. Dropped TEMPSTATE[] and only use DEVPRESENT[] to mark devices state. Adjusted webpages for this switch in responses. Adjusted MySQL mon_fermenters enum values too. Rename some global Config records to better reflect their real use.Added one-wire json records and websocket. Announce when some onewire device changes. Add UNITS JSON command without parameter. Dropped global tempFormat setting that was never used.

configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
thermferm/Makefile file | annotate | diff | comparison | revisions
thermferm/devices.c file | annotate | diff | comparison | revisions
thermferm/mqtt.c file | annotate | diff | comparison | revisions
thermferm/one-wire.c file | annotate | diff | comparison | revisions
thermferm/one-wire.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
thermferm/websocket.c file | annotate | diff | comparison | revisions
www-thermferm/getroom.php file | annotate | diff | comparison | revisions
www-thermferm/getstate.php file | annotate | diff | comparison | revisions
www-thermferm/global.php file | annotate | diff | comparison | revisions
www-thermferm/index.php file | annotate | diff | comparison | revisions
www-thermferm/js/index.js file | annotate | diff | comparison | revisions
www-thermferm/liveview.php file | annotate | diff | comparison | revisions
www/js/fermenter.js file | annotate | diff | comparison | revisions
--- a/configure	Sat Apr 20 11:48:20 2024 +0200
+++ b/configure	Mon Apr 22 11:33:04 2024 +0200
@@ -2037,7 +2037,7 @@
 
 
 PACKAGE="mbsePi-apps"
-VERSION="0.9.19a1"
+VERSION="0.9.19a2"
 COPYRIGHT="Copyright (C) 2014-2024 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2024"
 
--- a/configure.ac	Sat Apr 20 11:48:20 2024 +0200
+++ b/configure.ac	Mon Apr 22 11:33:04 2024 +0200
@@ -8,7 +8,7 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="mbsePi-apps"
-VERSION="0.9.19a1"
+VERSION="0.9.19a2"
 COPYRIGHT="Copyright (C) 2014-2024 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2024"
 AC_SUBST(PACKAGE)
--- a/thermferm/Makefile	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/Makefile	Mon Apr 22 11:33:04 2024 +0200
@@ -62,7 +62,7 @@
 lcd-pcf8574.o: thermferm.h lcd-pcf8574.h slcd.h
 lock.o: lock.h thermferm.h
 mqtt.o: thermferm.h rdconfig.h devices.h xutil.h delay.h mqtt.h websocket.h
-one-wire.o: thermferm.h statetbl.h one-wire.h devices.h delay.h futil.h xutil.h
+one-wire.o: thermferm.h statetbl.h one-wire.h devices.h delay.h websocket.h futil.h xutil.h
 panel.o: thermferm.h delay.h lcd-pcf8574.h slcd.h panel.h
 pid.o: thermferm.h pid.h
 rc-switch.o: thermferm.h xutil.h delay.h rc-switch.h
--- a/thermferm/devices.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/devices.c	Mon Apr 22 11:33:04 2024 +0200
@@ -355,7 +355,7 @@
     int			tmp, present;
 
     if (uuid == NULL)
-	return 0;
+	return DEVPRESENT_UNDEF;
 
     for (device = Config.devices; device; device = device->next) {
 	if (! strcmp(uuid, device->uuid)) {
--- a/thermferm/mqtt.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/mqtt.c	Mon Apr 22 11:33:04 2024 +0200
@@ -38,7 +38,7 @@
 extern const char	UNITMODE[5][8];
 extern const char	UNITSTAGE[4][12];
 extern const char	PROFSTATE[5][6];
-extern const char	TEMPSTATE[3][8];
+extern const char	DEVPRESENT[4][6];
 
 int			Sequence = 0;
 
@@ -932,7 +932,7 @@
 	payload = xstrcat(payload, (char *)",\"air\":{\"address\":\"");
 	payload = xstrcat(payload, unit->air_address);
 	payload = xstrcat(payload, (char *)"\",\"state\":\"");
-	payload = xstrcat(payload, (char *)TEMPSTATE[unit->air_state]);
+	payload = xstrcat(payload, (char *)DEVPRESENT[unit->air_state]);
         payload = xstrcat(payload, (char *)"\",\"temperature\":");
         sprintf(buf, "%.3f", unit->air_temperature / 1000.0);
         payload = xstrcat(payload, buf);
@@ -949,7 +949,7 @@
 	payload = xstrcat(payload, (char *)",\"beer\":{\"address\":\"");
 	payload = xstrcat(payload, unit->beer_address);
 	payload = xstrcat(payload, (char *)"\",\"state\":\"");
-	payload = xstrcat(payload, (char *)TEMPSTATE[unit->beer_state]);
+	payload = xstrcat(payload, (char *)DEVPRESENT[unit->beer_state]);
         payload = xstrcat(payload, (char *)"\",\"temperature\":");
         sprintf(buf, "%.3f", unit->beer_temperature / 1000.0);
         payload = xstrcat(payload, buf);
@@ -966,7 +966,7 @@
 	payload = xstrcat(payload, (char *)",\"chiller\":{\"address\":\"");
 	payload = xstrcat(payload, unit->chiller_address);
 	payload = xstrcat(payload, (char *)"\",\"state\":\"");
-	payload = xstrcat(payload, (char *)TEMPSTATE[unit->chiller_state]);
+	payload = xstrcat(payload, (char *)DEVPRESENT[unit->chiller_state]);
 	payload = xstrcat(payload, (char *)"\",\"temperature\":");
 	sprintf(buf, "%.3f", unit->chiller_temperature / 1000.0);
 	payload = xstrcat(payload, buf);
@@ -1347,7 +1347,7 @@
 	    payload = xstrcat(payload, buf);
 	    comma = true;
 	}
-	if (Config.temp_address) {
+	if (Config.temp_uuid) {
 	    if (comma)
 		payload = xstrcat(payload, (char *)",");
 	    payload = xstrcat(payload, (char *)"\"room\":");
@@ -1429,37 +1429,37 @@
     payload = xstrcat(payload, (char *)"\",\"FW\":\"");
     payload = xstrcat(payload, (char *)VERSION);
     payload = xstrcat(payload, (char *)"\",\"server_port\":");
-    sprintf(buf, "%d", Config.my_port);
+    sprintf(buf, "%d", Config.server_port);
     payload = xstrcat(payload, buf);
     payload = xstrcat(payload, (char *)",\"websocket_port\":");
     sprintf(buf, "%d", Config.websocket_port);
     payload = xstrcat(payload, buf);
 
-    if (Config.temp_address || Config.hum_address) {
+    if (Config.temp_uuid || Config.hum_uuid) {
         payload = xstrcat(payload, (char *)",\"THB\":{");
-        if (Config.temp_address) {
-            payload = xstrcat(payload, (char *)"\"temperature\":{\"address\":\"");
-	    payload = xstrcat(payload, Config.temp_address);
+        if (Config.temp_uuid) {
+            payload = xstrcat(payload, (char *)"\"temperature\":{\"uuid\":\"");
+	    payload = xstrcat(payload, Config.temp_uuid);
 	    payload = xstrcat(payload, (char *)"\",\"state\":\"");
-	    payload = xstrcat(payload, (char *)TEMPSTATE[Config.temp_state]);
+	    payload = xstrcat(payload, (char *)DEVPRESENT[Config.temp_state]);
 	    payload = xstrcat(payload, (char *)"\",\"value\":");
             sprintf(buf, "%d", Config.temp_value);
             payload = xstrcat(payload, buf);
 	    payload = xstrcat(payload, (char *)"}");
         }
-        if (Config.temp_address && Config.hum_address)
+        if (Config.temp_uuid && Config.hum_uuid)
             payload = xstrcat(payload, (char *)",");
-        if (Config.hum_address) {
-            payload = xstrcat(payload, (char *)"\"humidity\":{\"address\":\"");
-	    payload = xstrcat(payload, Config.hum_address);
+        if (Config.hum_uuid) {
+            payload = xstrcat(payload, (char *)"\"humidity\":{\"uuid\":\"");
+	    payload = xstrcat(payload, Config.hum_uuid);
             payload = xstrcat(payload, (char *)"\",\"state\":\"");
-            payload = xstrcat(payload, (char *)TEMPSTATE[Config.hum_state]);
+            payload = xstrcat(payload, (char *)DEVPRESENT[Config.hum_state]);
             payload = xstrcat(payload, (char *)"\",\"value\":");
             sprintf(buf, "%d", Config.hum_value);
             payload = xstrcat(payload, buf);
 	    payload = xstrcat(payload, (char *)"}");
         }
-	if (Config.temp_address || Config.hum_address)
+	if (Config.temp_uuid || Config.hum_uuid)
             payload = xstrcat(payload, (char *)",");
 	payload = xstrcat(payload, (char *)"\"index\":");
 	sprintf(buf, "%d", Config.temp_hum_idx);
@@ -1571,20 +1571,20 @@
 	comma = true;
     }
 
-    if (Config.temp_address || Config.hum_address) {
+    if (Config.temp_uuid || Config.hum_uuid) {
 	if (comma)
 	    payload = xstrcat(payload, (char *)",");
 	payload = xstrcat(payload, (char *)"\"THB\":{");
-	if (Config.temp_address) {
+	if (Config.temp_uuid) {
 	    payload = xstrcat(payload, (char *)"\"temperature\":");
-	    sprintf(buf, "%.1f", Config.temp_value / 1000.0);
+	    sprintf(buf, "%d", Config.temp_value);
 	    payload = xstrcat(payload, buf);
 	}
-	if (Config.temp_address && Config.hum_address)
+	if (Config.temp_uuid && Config.hum_uuid)
 	    payload = xstrcat(payload, (char *)",");
-	if (Config.hum_address) {
+	if (Config.hum_uuid) {
 	    payload = xstrcat(payload, (char *)"\"humidity\":");
-	    sprintf(buf, "%.1f", Config.hum_value / 1000.0);
+	    sprintf(buf, "%d", Config.hum_value);
 	    payload = xstrcat(payload, buf);
 	}
 	payload = xstrcat(payload, (char *)"}");
@@ -1698,7 +1698,7 @@
     free(payload);
     payload = NULL;
 
-    if ((Config.temp_address || Config.hum_address) && Config.temp_hum_idx) {
+    if ((Config.temp_uuid || Config.hum_uuid) && Config.temp_hum_idx) {
 	sprintf(sidx, "%d", Config.temp_hum_idx);
 	sprintf(buf, "%.1f;%.1f;0", Config.temp_value / 1000.0, Config.hum_value / 1000.0);
 
--- a/thermferm/one-wire.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/one-wire.c	Mon Apr 22 11:33:04 2024 +0200
@@ -25,6 +25,7 @@
 #include "one-wire.h"
 #include "devices.h"
 #include "delay.h"
+#include "websocket.h"
 #include "futil.h"
 #include "xutil.h"
 
@@ -33,6 +34,8 @@
 
 extern sys_config	Config;
 extern pthread_mutex_t	mutexes[5];
+extern const char	DEVPRESENT[4][6];
+
 
 int			my_one_wire_state = 0;
 int			my_one_wire_shutdown = 0;
@@ -41,6 +44,58 @@
 
 static int one_wire(void);
 
+
+/*
+ * Return json data for one device.
+ */
+char *one_wire_json(w1_list *dev_w1)
+{
+    char        *payload;
+    char        vbuf[64];
+
+    payload = xstrcpy((char *)"{\"address\":\"");
+    payload = xstrcat(payload, dev_w1->address);
+    payload = xstrcat(payload, (char *)"\",\"family\":\"");
+    payload = xstrcat(payload, dev_w1->family);
+    payload = xstrcat(payload, (char *)"\",\"present\":\"");
+    payload = xstrcat(payload, (char *)DEVPRESENT[dev_w1->present]);
+    payload = xstrcat(payload, (char *)"\",\"value\":");
+    snprintf(vbuf, 63, "%d", dev_w1->value);
+    payload = xstrcat(payload, vbuf);
+    payload = xstrcat(payload, (char *)"\",\"timestamp\":");
+    snprintf(vbuf, 63, "%ld", (long)dev_w1->timestamp);
+    payload = xstrcat(payload, vbuf);
+    payload = xstrcat(payload, (char *)"}");
+
+    return payload;
+}
+
+
+void one_wire_ws(void)
+{
+    bool	comma = false;
+    char	*payload = NULL, *payloadu = NULL;
+    w1_list	*dev_w1;
+
+    payload = xstrcpy((char *)"{\"type\":\"onewire\",\"metric\":[");
+    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
+        if (comma)
+            payload = xstrcat(payload, (char *)",");
+        payloadu = one_wire_json(dev_w1);
+        payload = xstrcat(payload, payloadu);
+        comma = true;
+        free(payloadu);
+        payloadu = NULL;
+    }
+    payload = xstrcat(payload, (char *)"]}");
+    syslog(LOG_NOTICE, "%s", payload);
+    ws_broadcast(payload);
+    free(payload);
+    payload = NULL;
+}
+
+
+
 void *my_one_wire_loop(void *threadid)
 {
     my_one_wire_state = 1;
@@ -69,13 +124,15 @@
     ScanDel,
     Read2413,
     ReadTemp,
-    Missing
+    Missing,
+    Websocket
 SM_NAMES
     (char *)"ScanNew",
     (char *)"ScanDel",
     (char *)"Read2413",
     (char *)"ReadTemp",
-    (char *)"Missing"
+    (char *)"Missing",
+    (char *)"Websocket"
 SM_EDECL
 
     int			found, i, rc, value, conv_time;
@@ -84,6 +141,7 @@
     w1_list		*dev_w1, *n_w1, *cur_w1 = NULL;
     char		buffer[25], w1type[10], *devfile = NULL;
     uint8_t		state, output, newval;
+    bool		changed;
 
 SM_START(ScanNew)
 
@@ -93,6 +151,7 @@
 	SM_SUCCESS;
     }
 
+    changed = false;
     /*
      * Scan for current one-wire devices.
      */
@@ -116,12 +175,13 @@
 	    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
 		if (strcmp(dev_w1->address, buffer) == 0) {
 		    found = TRUE;
-		    dev_w1->timestamp = time(NULL);
 		    if (dev_w1->present != DEVPRESENT_YES) {
 			syslog(LOG_NOTICE, "One-wire device %s is back", buffer);
 			pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 			dev_w1->present = DEVPRESENT_YES;
+			dev_w1->timestamp = time(NULL);
 			pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
+			changed = true;
 			for (device = Config.devices; device; device = device->next) {
 			    if (strcmp(dev_w1->address, device->address) == 0) {
 //				pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -143,6 +203,7 @@
 		n_w1->present = DEVPRESENT_YES;
 		n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1;
 		n_w1->timestamp = time(NULL);
+		changed = true;
 
 		pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 		if (w1_devices == NULL) {
@@ -185,7 +246,9 @@
 	    syslog(LOG_NOTICE, "One-wire device %s is missing", dev_w1->address);
 	    pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 	    dev_w1->present = DEVPRESENT_NO;
+	    dev_w1->timestamp = time(NULL);
 	    pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
+	    changed = true;
 	    for (device = Config.devices; device; device = device->next) {
 		if (strcmp(dev_w1->address, device->address) == 0) {
 //		    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -239,6 +302,8 @@
 			    if (newval != dev_w1->value) {
 			    	syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, i, state, dev_w1->value, newval);
 			    	dev_w1->value = newval;
+				dev_w1->timestamp = time(NULL);
+				changed = true;
 			    }
 
 //			    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -273,6 +338,8 @@
 				if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) {
 				    syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, newval);
 				    dev_w1->value = newval;
+				    dev_w1->timestamp = time(NULL);
+				    changed = true;
 				}
 			    }
 			}
@@ -335,8 +402,11 @@
 		    mDelay(conv_time);
 		    if ((fgets(buffer, 25, fp))) {
 			sscanf(buffer, "%d", &value);
-//			if (cur_w1->value != value)
+			if (cur_w1->value != value) {
+			    dev_w1->timestamp = time(NULL);
+			    changed = true;
 //			    syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value);
+			}
 			cur_w1->value = value;		/* devices.c will pick this up */
 		    } else {
 			syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address);
@@ -374,7 +444,19 @@
 	SM_SUCCESS;
     }
 
-    sleep(1);
+    SM_PROCEED(Websocket);
+
+SM_STATE(Websocket)
+
+    for (i = 0; i < 10; i++) {
+	if (my_one_wire_shutdown) {
+	    SM_SUCCESS;
+	}
+
+	mDelay(100);
+	if (changed && i == 5)
+	    one_wire_ws();
+    }
     SM_PROCEED(ScanNew);
 
 SM_END
--- a/thermferm/one-wire.h	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/one-wire.h	Mon Apr 22 11:33:04 2024 +0200
@@ -6,6 +6,8 @@
 #ifndef	ONE_WIRE_H
 #define	ONE_WIRE_H
 
+char *one_wire_json(w1_list *dev_w1);
+
 void *my_one_wire_loop(void *);
 
 #endif
--- a/thermferm/rdconfig.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/rdconfig.c	Mon Apr 22 11:33:04 2024 +0200
@@ -33,7 +33,6 @@
 
 #define MY_ENCODING "utf-8"
 
-const char	TEMPSTATE[3][8] = { "OK", "MISSING", "ERROR" };
 const char      UNITMODE[5][8]	= { "OFF", "NONE", "FRIDGE", "BEER", "PROFILE" };
 const char	UNITSTAGE[4][12] = { "PRIMARY", "SECONDARY", "TERTIARY", "CARBONATION" };
 const char	PROFSTATE[5][6]	= { "OFF", "PAUSE", "RUN", "DONE", "ABORT" };
@@ -59,14 +58,14 @@
 	free(Config.name);
     Config.name = NULL;
 
-    Config.my_port = 6554;
-    Config.tempFormat = 'C';
-    if (Config.temp_address)
-	free(Config.temp_address);
-    if (Config.hum_address)
-	free(Config.hum_address);
+    Config.server_port = 6554;
+    Config.websocket_port = 8020;
+    if (Config.temp_uuid)
+	free(Config.temp_uuid);
+    if (Config.hum_uuid)
+	free(Config.hum_uuid);
     Config.temp_hum_idx = 0;
-    Config.temp_address = Config.hum_address = NULL;
+    Config.temp_uuid = Config.hum_uuid = NULL;
     Config.temp_value = 20000;
     Config.temp_state = Config.hum_state = 1;	// missing
     Config.hum_value = 50000;
@@ -219,13 +218,13 @@
 
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", Config.name);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", Config.uuid);
-    xmlTextWriterWriteFormatElement(writer, BAD_CAST "LISTEN_PORT", "%d", Config.my_port);
-    xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMPFORMAT", "%c", Config.tempFormat);
+    xmlTextWriterWriteFormatElement(writer, BAD_CAST "SERVER_PORT", "%d", Config.server_port);
+    xmlTextWriterWriteFormatElement(writer, BAD_CAST "WS_PORT", "%d", Config.websocket_port);
 
-    xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_ADDRESS", "%s", Config.temp_address);
+    xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_UUID", "%s", Config.temp_uuid);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_STATE", "%d", Config.temp_state);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_VALUE", "%d", Config.temp_value);
-    xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_ADDRESS", "%s", Config.hum_address);
+    xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_UUID", "%s", Config.hum_uuid);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_STATE", "%d", Config.hum_state);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "HUM_VALUE", "%d", Config.hum_value);
     xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMP_HUM_IDX", "%d", Config.temp_hum_idx);
@@ -238,7 +237,6 @@
     	xmlTextWriterWriteFormatElement(writer, BAD_CAST "MQTT_USER", "%s", Config.mqtt_username);
     	xmlTextWriterWriteFormatElement(writer, BAD_CAST "MQTT_PASS", "%s", Config.mqtt_password);
     }
-    xmlTextWriterWriteFormatElement(writer, BAD_CAST "WS_PORT", "%d", Config.websocket_port);
 
     /* 
      * Start an element named "LCDS" as child of THERMFERM.
@@ -579,7 +577,7 @@
     unit->volume = unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
     unit->air_temperature = unit->beer_temperature = unit->chiller_temperature = unit->beer_set_lo = unit->beer_set_hi = \
 			    unit->fridge_set_lo = unit->fridge_set_hi = unit->profile_inittemp_lo = unit->profile_inittemp_hi = 20.0;
-    unit->air_state = unit->beer_state = unit->chiller_state = 1; // missing
+    unit->air_state = unit->beer_state = unit->chiller_state = DEVPRESENT_NO; // missing
     unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = \
 			 unit->light_state = unit->light_timer = unit->psu_state = unit->mode = unit->prof_state = unit->stage = 0;
     unit->air_idx = unit->beer_idx = unit->chiller_idx = unit->heater_idx = unit->cooler_idx = unit->fan_idx = \
@@ -1590,22 +1588,17 @@
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
 	    Config.name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"SERVER_PORT")) || (!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) {
 	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	    if (sscanf((const char *)key, "%d", &ival) == 1)
-		Config.my_port = ival;
+		Config.server_port = ival;
 	    xmlFree(key);
 	}
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMPFORMAT"))) {
-	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-	    Config.tempFormat = key[0];
-	    xmlFree(key);
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_UUID")) || (!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_ADDRESS"))) {
+	    Config.temp_uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_ADDRESS"))) {
-	    Config.temp_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-	}
-	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HUM_ADDRESS"))) {
-	    Config.hum_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"HUM_UUID")) || (!xmlStrcmp(cur->name, (const xmlChar *)"HUM_ADDRESS"))) {
+	    Config.hum_uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMP_HUM_IDX"))) {
 	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
--- a/thermferm/server.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/server.c	Mon Apr 22 11:33:04 2024 +0200
@@ -36,7 +36,6 @@
 extern sys_config       Config;
 extern const char	UNITMODE[5][8];
 extern const char	UNITSTAGE[4][12];
-extern const char	TEMPSTATE[3][8];
 extern const char	DEVTYPE[8][6];
 extern const char	DEVPRESENT[4][6];
 extern const char	DEVDIR[7][11];
@@ -652,13 +651,12 @@
 	srv_send(s, (char *)"213 Global Settings record follows:");
 	srv_send(s, (char *)"RELEASE,%s", VERSION);
 	srv_send(s, (char *)"NAME,%s", Config.name);
-	srv_send(s, (char *)"PORT,%d", Config.my_port);
-	srv_send(s, (char *)"TEMPFORMAT,%c", Config.tempFormat);
-	srv_send(s, (char *)"TEMP_ADDRESS,%s", Config.temp_address);
-	srv_send(s, (char *)"TEMP_STATE,%s", TEMPSTATE[Config.temp_state]);
+	srv_send(s, (char *)"PORT,%d", Config.server_port);
+	srv_send(s, (char *)"TEMP_UUID,%s", Config.temp_uuid);
+	srv_send(s, (char *)"TEMP_STATE,%s", DEVPRESENT[Config.temp_state]);
 	srv_send(s, (char *)"TEMP_VALUE,%.1f", Config.temp_value / 1000.0);
-	srv_send(s, (char *)"HUM_ADDRESS,%s", Config.hum_address);
-	srv_send(s, (char *)"HUM_STATE,%s", TEMPSTATE[Config.hum_state]);
+	srv_send(s, (char *)"HUM_UUID,%s", Config.hum_uuid);
+	srv_send(s, (char *)"HUM_STATE,%s", DEVPRESENT[Config.hum_state]);
 	srv_send(s, (char *)"HUM_VALUE,%.0f", Config.hum_value / 1000.0);
 	srv_send(s, (char *)"TEMP_HUM_IDX,%d", Config.temp_hum_idx);
 	srv_send(s, (char *)"LCD_COLS,%d", Config.lcd_cols);
@@ -714,43 +712,36 @@
 
 		    } else if (val && (strcmp(kwd, (char *)"PORT") == 0)) {
 			if (sscanf(val, "%d", &ival) == 1) {
-			    if (Config.my_port != ival)
-			    	syslog(LOG_NOTICE, "Global port %d to %d", Config.my_port, ival);
-			    Config.my_port = ival;
-			}
-
-		    } else if (val && (strcmp(kwd, (char *)"TEMPFORMAT") == 0)) {
-			if ((val[0] == 'C') || (val[0] == 'F')) {
-			    if (Config.tempFormat != val[0])
-				syslog(LOG_NOTICE, "Global port %c to %c", Config.tempFormat, val[0]);
-			    Config.tempFormat = val[0];
+			    if (Config.server_port != ival)
+			    	syslog(LOG_NOTICE, "Global server port %d to %d", Config.server_port, ival);
+			    Config.server_port = ival;
 			}
 
-		    } else if (strcmp(kwd, (char *)"TEMP_ADDRESS") == 0) {
-			if (val && Config.temp_address && (strcmp(val, Config.temp_address)))
-			    syslog(LOG_NOTICE, "Global temperature address `%s' to `%s'", Config.temp_address, val);
-		        if (Config.temp_address) {
-			    device_count(FALSE, Config.temp_address);
-			    free(Config.temp_address);
+		    } else if (strcmp(kwd, (char *)"TEMP_UUID") == 0) {
+			if (val && Config.temp_uuid && (strcmp(val, Config.temp_uuid)))
+			    syslog(LOG_NOTICE, "Global temperature uuid `%s' to `%s'", Config.temp_uuid, val);
+		        if (Config.temp_uuid) {
+			    device_count(FALSE, Config.temp_uuid);
+			    free(Config.temp_uuid);
 			}
 			if (val) {
-			    Config.temp_address = xstrcpy(val);
-			    device_count(TRUE, Config.temp_address);
+			    Config.temp_uuid = xstrcpy(val);
+			    device_count(TRUE, Config.temp_uuid);
 			} else
-			    Config.temp_address = NULL;
+			    Config.temp_uuid = NULL;
 
-		    } else if (strcmp(kwd, (char *)"HUM_ADDRESS") == 0) {
-			if (val && Config.hum_address && (strcmp(val, Config.hum_address)))
-			    syslog(LOG_NOTICE, "Global humidity address `%s' to `%s'", Config.hum_address, val);
-			if (Config.hum_address) {
-			    device_count(FALSE, Config.hum_address);
-			    free(Config.hum_address);
+		    } else if (strcmp(kwd, (char *)"HUM_UUID") == 0) {
+			if (val && Config.hum_uuid && (strcmp(val, Config.hum_uuid)))
+			    syslog(LOG_NOTICE, "Global humidity uuid `%s' to `%s'", Config.hum_uuid, val);
+			if (Config.hum_uuid) {
+			    device_count(FALSE, Config.hum_uuid);
+			    free(Config.hum_uuid);
 			}
 			if (val) {
-			    Config.hum_address = xstrcpy(val);
-			    device_count(TRUE, Config.hum_address);
+			    Config.hum_uuid = xstrcpy(val);
+			    device_count(TRUE, Config.hum_uuid);
 			} else
-			    Config.hum_address = NULL;
+			    Config.hum_uuid = NULL;
 
 		    } else if (val && (strcmp(kwd, (char *)"TEMP_HUM_IDX") == 0)) {
 			if (sscanf(val, "%d", &ival) == 1) {
@@ -1402,6 +1393,52 @@
 	return 0;
     }
 
+    if (strcmp(opt, (char *)"JSON") == 0) {
+        char    *payload = NULL, *payloadu = NULL;
+        bool    comma = false;
+
+        if (param == NULL) {
+            srv_send(s, (char *)"212 Units json list follows:");
+            payload = xstrcpy((char *)"[");
+            for (unit = Config.units; unit; unit = unit->next) {
+                if (comma)
+                    payload = xstrcat(payload, (char *)",");
+                payloadu = unit_data(unit, true);
+		payload = xstrcat(payload, payloadu);
+                comma = true;
+                free(payloadu);
+                payloadu = NULL;
+            }
+            payload = xstrcat(payload, (char *)"]");
+            srv_send(s, payload);
+            srv_send(s, (char *)".");
+            free(payload);
+            payload = NULL;
+            return 0;
+        } else {
+            syslog(LOG_NOTICE, "UNIT JSON %s", param);
+            for (unit = Config.units; unit; unit = unit->next) {
+                if (strcmp(param, unit->uuid) == 0) {
+                    srv_send(s, (char *)"213 Unit json data follows:");
+                    payload = xstrcpy((char *)"{\"type\":\"fermenter\",\"unit\":\"");
+                    payload = xstrcat(payload, unit->alias);
+                    payload = xstrcat(payload, (char *)"\",\"metric\":");
+                    payloadu = unit_data(unit, false);
+                    payload = xstrcat(payload, payloadu);
+                    payload = xstrcat(payload, (char *)"}");
+                    srv_send(s, payload);
+                    free(payload);
+                    free(payloadu);
+                    payload = payloadu = NULL;
+                    srv_send(s, (char *)".");
+                    return 0;
+                }
+            }
+            srv_send(s, (char *)"440 No such unit");
+            return 0;
+        }
+    }
+
     if (param == NULL) {
 	srv_send(s, (char *)"502 Parameter missing");
 	return 0;
@@ -1429,7 +1466,7 @@
 			unit->profile_duration = unit->profile_totalsteps = 0;
 	unit->profile_steps = NULL;
 	unit->volume = unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
-	unit->air_state = unit->beer_state = unit->chiller_state = 1;
+	unit->air_state = unit->beer_state = unit->chiller_state = DEVPRESENT_NO;
 	unit->air_temperature = unit->beer_temperature = unit->chiller_temperature = 20000;
 	unit->beer_set_lo = unit->beer_set_hi = unit->fridge_set_lo = unit->fridge_set_hi = unit->profile_inittemp_lo = unit->profile_inittemp_hi =20.0;
 	unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = \
@@ -1512,16 +1549,16 @@
 		srv_send(s, (char *)"STAGE,%s", UNITSTAGE[unit->stage]);
 		srv_send(s, (char *)"VOLUME,%2f", unit->volume);
 		srv_send(s, (char *)"AIR_ADDRESS,%s", unit->air_address);
-		srv_send(s, (char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]);
+		srv_send(s, (char *)"AIR_STATE,%s", DEVPRESENT[unit->air_state]);
 		srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0);
 		srv_send(s, (char *)"AIR_IDX,%d", unit->air_idx);
 		srv_send(s, (char *)"BEER_ADDRESS,%s", MBSE_SS(unit->beer_address));
 		srv_send(s, (char *)"BEER_ADDRESS2,%s", MBSE_SS(unit->beer_address2));
-		srv_send(s, (char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]);
+		srv_send(s, (char *)"BEER_STATE,%s", DEVPRESENT[unit->beer_state]);
 		srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0);
 		srv_send(s, (char *)"BEER_IDX,%d", unit->beer_idx);
 		srv_send(s, (char *)"CHILLER_ADDRESS,%s", MBSE_SS(unit->chiller_address));
-		srv_send(s, (char *)"CHILLER_STATE,%s", TEMPSTATE[unit->chiller_state]);
+		srv_send(s, (char *)"CHILLER_STATE,%s", DEVPRESENT[unit->chiller_state]);
 		srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", unit->chiller_temperature / 1000.0);
 		srv_send(s, (char *)"CHILLER_IDX,%d", unit->chiller_idx);
 		srv_send(s, (char *)"HEATER_ADDRESS,%s", unit->heater_address);
@@ -1602,32 +1639,6 @@
 	return 0;
     }
 
-    if (strcmp(opt, (char *)"JSON") == 0) {
-	syslog(LOG_NOTICE, "UNIT JSON %s", param);
-        for (unit = Config.units; unit; unit = unit->next) {
-            if (strcmp(param, unit->uuid) == 0) {
-		char	*payload, *payloadu;
-
-		srv_send(s, (char *)"213 Unit json data follows:");
-
-		payload = xstrcpy((char *)"{\"type\":\"fermenter\",\"unit\":\"");
-		payload = xstrcat(payload, unit->alias);
-		payload = xstrcat(payload, (char *)"\",\"metric\":");
-		payloadu = unit_data(unit, false);
-		payload = xstrcat(payload, payloadu);
-		payload = xstrcat(payload, (char *)"}");
-		srv_send(s, payload);
-		free(payload);
-		free(payloadu);
-		payload = payloadu = NULL;
-		srv_send(s, (char *)".");
-		return 0;
-	    }
-	}
-	srv_send(s, (char *)"440 No such unit");
-	return 0;
-    }
-
     if (strcmp(opt, (char *)"PUT") == 0) {
 	/*
 	 * Block main process
@@ -2272,7 +2283,7 @@
     memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
     myaddr_in.sin_family = AF_INET;
     myaddr_in.sin_addr.s_addr = INADDR_ANY;
-    myaddr_in.sin_port = htons(Config.my_port);
+    myaddr_in.sin_port = htons(Config.server_port);
 
     ls = socket(AF_INET, SOCK_STREAM, 0);
     if (ls == -1) {
--- a/thermferm/thermferm.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/thermferm.c	Mon Apr 22 11:33:04 2024 +0200
@@ -1033,18 +1033,15 @@
     unit->alarm_flag = 0;
 
     if (unit->air_address) {
-	rc = device_in(unit->air_address, &temp);
+	unit->air_state = rc = device_in(unit->air_address, &temp);
 	if (rc == DEVPRESENT_YES) {
 	    if (unit->air_temperature != temp) {
 		unit->mqtt_flag |= MQTT_FLAG_DATA;
 	    }
 	    unit->air_temperature = temp;
-	    unit->air_state = 0;
-	} else if (rc == DEVPRESENT_ERROR) {
-	    unit->air_state = 1;
-	} else {
-	    unit->air_state = 2;
 	}
+    } else {
+	unit->air_state = DEVPRESENT_NO;
     }
 
     if (unit->beer_address) {
@@ -1053,32 +1050,27 @@
 	    /* Read alternative sensor */
 	    rc = device_in(unit->beer_address2, &temp);
 	}
+	unit->beer_state = rc;
 	if (rc == DEVPRESENT_YES) {
 	    if (unit->beer_temperature != temp) {
 		unit->mqtt_flag |= MQTT_FLAG_DATA;
 	    }
 	    unit->beer_temperature = temp;
-	    unit->beer_state = 0;
-	} else if (rc == DEVPRESENT_ERROR) {
-	    unit->beer_state = 1;
-	} else {
-	    unit->beer_state = 2;
 	}
+    } else {
+	unit->beer_state = DEVPRESENT_NO;
     }
 
     if (unit->chiller_address) {
-	rc = device_in(unit->chiller_address, &temp);
+	unit->chiller_state = rc = device_in(unit->chiller_address, &temp);
 	if (rc == DEVPRESENT_YES) {
 	    if (unit->chiller_temperature != temp) {
 		unit->mqtt_flag |= MQTT_FLAG_DATA;
 	    }
 	    unit->chiller_temperature = temp;
-	    unit->chiller_state = 0;
-	} else if (rc == DEVPRESENT_ERROR) {
-	    unit->chiller_state = 1;
-	} else {
-	    unit->chiller_state = 2;
 	}
+    } else {
+	unit->chiller_state = DEVPRESENT_NO;
     }
 
     /*
@@ -1733,20 +1725,15 @@
     lcd_buf_write(row, "Room temp N/A       ");
     pthread_mutex_unlock(&mutexes[LOCK_LCD]);
     int updateHT = 0;
-    if (Config.temp_address) {
-	rc = device_in(Config.temp_address, &temp);
+    if (Config.temp_uuid) {
+	Config.temp_state = rc = device_in(Config.temp_uuid, &temp);
 	if (rc == DEVPRESENT_YES) {
 	    if (Config.temp_value != temp)
 		updateHT = 1;
 	    Config.temp_value = temp;
-	    Config.temp_state = 0;
 	    pthread_mutex_lock(&mutexes[LOCK_LCD]);
 	    lcd_buf_write(row, "Room temp %.1f%c    ", Config.temp_value / 1000.0, 0x01);
 	    pthread_mutex_unlock(&mutexes[LOCK_LCD]);
-	} else if (rc == DEVPRESENT_ERROR) {
-	    Config.temp_state = 1;
-	} else {
-	    Config.temp_state = 2;
 	}
 	mDelay(10);
     }
@@ -1755,20 +1742,15 @@
     pthread_mutex_lock(&mutexes[LOCK_LCD]);
     lcd_buf_write(row, " Humidity N/A       ");
     pthread_mutex_unlock(&mutexes[LOCK_LCD]);
-    if (Config.hum_address) {
-	rc = device_in(Config.hum_address, &temp);
+    if (Config.hum_uuid) {
+	Config.hum_state = rc = device_in(Config.hum_uuid, &temp);
 	if (rc == DEVPRESENT_YES) {
 	    if (Config.hum_value != temp)
 		updateHT = 1;
 	    Config.hum_value = temp;
-	    Config.hum_state = 0;
 	    pthread_mutex_lock(&mutexes[LOCK_LCD]);
 	    lcd_buf_write(row, " Humidity %.1f%%     ", Config.hum_value / 1000.0);
 	    pthread_mutex_unlock(&mutexes[LOCK_LCD]);
-	} else if (rc == DEVPRESENT_ERROR) {
-	    Config.hum_state = 1;
-	} else {
-	    Config.hum_state = 2;
 	}
 	mDelay(10);
     }
--- a/thermferm/thermferm.h	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/thermferm.h	Mon Apr 22 11:33:04 2024 +0200
@@ -363,12 +363,11 @@
 
 typedef struct _sys_config {
     char		*name;			/* Configuration name		*/
-    int			my_port;		/* my client/server port	*/
-    unsigned char	tempFormat;		/* Temperature format, C or F	*/
-    char		*temp_address;		/* Environment temperature	*/
+    int			server_port;		/* my client/server port	*/
+    char		*temp_uuid;		/* Environment temperature	*/
     int			temp_state;		/* 0=ok, 1=missing, 2=error	*/
     int			temp_value;		/* Air temperature in C * 1000	*/
-    char		*hum_address;		/* Environment huminity		*/
+    char		*hum_uuid;		/* Environment huminity		*/
     int			hum_state;		/* 0=ok, 1=missing, 2=error	*/
     int			hum_value;		/* Huminity in % * 1000		*/
     int			temp_hum_idx;		/* Domoticz idx			*/
@@ -377,7 +376,6 @@
     int			lcd_address;		/* LCD display i2c address	*/
     int			next_unit;		/* Next unit alias name		*/
     units_list		*units;			/* Fermenter units		*/
-//    profiles_list	*profiles;		/* Ferment profiles		*/
     devices_list	*devices;		/* Sensors and switches		*/
 #ifdef USE_SIMULATOR
     simulator_list	*simulators;		/* Simulators			*/
--- a/thermferm/websocket.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/websocket.c	Mon Apr 22 11:33:04 2024 +0200
@@ -35,8 +35,6 @@
 extern int		debug;
 extern const char	UNITMODE[5][8];
 extern const char	UNITSTAGE[4][12];
-//extern const char       PROFSTATE[5][6];
-//extern const char       TEMPSTATE[3][8];
 
 int			my_ws_shutdown = 0;
 int			my_ws_state = 0;
--- a/www-thermferm/getroom.php	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/getroom.php	Mon Apr 22 11:33:04 2024 +0200
@@ -41,11 +41,11 @@
 
 	if ($f[0] == "TEMP_STATE")
 		$temp_state = $f[1];
-	if (($f[0] == "TEMP_VALUE") && ($temp_state == "OK"))
+	if (($f[0] == "TEMP_VALUE") && ($temp_state == "YES"))
 		$temp_value = $f[1];
 	if ($f[0] == "HUM_STATE")
 		$hum_state = $f[1];
-	if (($f[0] == "HUM_VALUE") && ($hum_state == "OK"))
+	if (($f[0] == "HUM_VALUE") && ($hum_state == "YES"))
 		$hum_value = $f[1];
 	$j++;
     }
--- a/www-thermferm/getstate.php	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/getstate.php	Mon Apr 22 11:33:04 2024 +0200
@@ -58,15 +58,15 @@
 
 	if ($f[0] == "AIR_STATE")
 		$air_state = $f[1];
-	if (($f[0] == "AIR_TEMPERATURE") && ($air_state == "OK"))
+	if (($f[0] == "AIR_TEMPERATURE") && ($air_state == "YES"))
 		$air_temperature = $f[1];
 	if ($f[0] == "BEER_STATE")
 		$beer_state = $f[1];
-	if (($f[0] == "BEER_TEMPERATURE") && ($beer_state == "OK"))
+	if (($f[0] == "BEER_TEMPERATURE") && ($beer_state == "YES"))
 		$beer_temperature = $f[1];
 	if ($f[0] == "CHILLER_STATE")
 	    	$chiller_state = $f[1];
-	if (($f[0] == "CHILLER_TEMPERATURE") && ($chiller_state == "OK"))
+	if (($f[0] == "CHILLER_TEMPERATURE") && ($chiller_state == "YES"))
 	    	$chiller_temperature = $f[1];
 	if ($f[0] == "MODE")
 		$mode = $f[1];
--- a/www-thermferm/global.php	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/global.php	Mon Apr 22 11:33:04 2024 +0200
@@ -46,8 +46,8 @@
 	$cmd = array("GLOBAL PUT");
 	$cmd[] = "NAME,".$_POST['Name'];
 	$cmd[] = "PORT,".$_POST['Port'];
-	$cmd[] = "TEMP_ADDRESS,".$_POST['TempAddress'];
-	$cmd[] = "HUM_ADDRESS,".$_POST['HumAddress'];
+	$cmd[] = "TEMP_UUID,".$_POST['TempAddress'];
+	$cmd[] = "HUM_UUID,".$_POST['HumAddress'];
 	$cmd[] = "TEMP_HUM_IDX,".$_POST['TempHumIdx'];
 	if (isset($_POST['LCDcols']))
 	    $cmd[] = "LCD_COLS,".$_POST['LCDcols'];
@@ -173,7 +173,7 @@
 		$outstr .= '        <td class="editfield"><input type="text" name="Port" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
-	    if ($f[0] == "TEMP_ADDRESS") {
+	    if ($f[0] == "TEMP_UUID") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Room temperature sensor</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><select name="TempAddress">'.PHP_EOL;
@@ -194,7 +194,7 @@
 		$outstr .= '        </select></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
-	    if ($f[0] == "HUM_ADDRESS") {
+	    if ($f[0] == "HUM_UUID") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Room humidity sensor</td>'.PHP_EOL;
 		$outstr .= '        <td class="editfield"><select name="HumAddress">'.PHP_EOL;
--- a/www-thermferm/index.php	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/index.php	Mon Apr 22 11:33:04 2024 +0200
@@ -1,6 +1,6 @@
 <?php
 /*****************************************************************************
- * Copyright (C) 2014-2019
+ * Copyright (C) 2014-2024
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -128,11 +128,11 @@
 	    $version = $f[1];
 	if ($f[0] == "TEMP_STATE")
 	    $temp_state = $f[1];
-	if (($f[0] == "TEMP_VALUE") && ($temp_state == "OK"))
+	if (($f[0] == "TEMP_VALUE") && ($temp_state == "YES"))
 	    $temp_value = $f[1];
 	if ($f[0] == "HUM_STATE")
 	    $hum_state = $f[1];
-	if (($f[0] == "HUM_VALUE") && ($hum_state == "OK"))
+	if (($f[0] == "HUM_VALUE") && ($hum_state == "YES"))
 	    $hum_value = $f[1];
 	$j++;
     }
--- a/www-thermferm/js/index.js	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/js/index.js	Mon Apr 22 11:33:04 2024 +0200
@@ -24,8 +24,8 @@
 $(document).ready(function () {
     setInterval(function(){
       $.getJSON("getroom.php", function(data) {
-        $("#room_temp").html(data.temperature);
-        $("#room_hum").html(data.humidity);
+        $("#room_temp").html(data.temperature + ' &deg;C');
+        $("#room_hum").html(data.humidity + ' %');
       });
     }, 60000);
     // Create jqxTabs.
--- a/www-thermferm/liveview.php	Sat Apr 20 11:48:20 2024 +0200
+++ b/www-thermferm/liveview.php	Mon Apr 22 11:33:04 2024 +0200
@@ -67,7 +67,7 @@
 	    if (strcmp($vals[0], "AIR_STATE") == 0) {
 		$air_state = $vals[1];
 	    }
-	    if ((strcmp($vals[0], "AIR_TEMPERATURE") == 0) && ($air_state == 0)) {
+	    if ((strcmp($vals[0], "AIR_TEMPERATURE") == 0) && (strcmp($air_state, "YES") == 0)) {
 		$air_temperature = $vals[1];
 	    }
 	    if (strcmp($vals[0], "BEER_STATE") == 0) {
@@ -133,7 +133,7 @@
 	$outstr .= '    <script type="text/javascript">'.PHP_EOL;
 	$outstr .= '     $(document).ready(function () {'.PHP_EOL;
 
-	if ("$air_state" == "OK") {
+	if ("$air_state" == "YES") {
 	    $outstr .= '       $("#gaugeContainer_air'.$unr.'").jqxGauge({'.PHP_EOL;
 	    $outstr .= '         min: -5, max: 45, width: 275, height: 275,'.PHP_EOL;
 	    $outstr .= '         ranges: [{ startValue: -5, endValue:  0, style: { fill: \'#3399FF\', stroke: \'#3399FF\' }, endWidth: 10, startWidth: 10 },'.PHP_EOL;
@@ -150,7 +150,7 @@
 	    $outstr .= '       });'.PHP_EOL;
 	}
 
-	if ("$beer_state" == "OK") {
+	if ("$beer_state" == "YES") {
 	    $outstr .= '       $(\'#gaugeContainer_beer'.$unr.'\').jqxGauge({'.PHP_EOL;
 	    $outstr .= '         min: -5, max: 45, width: 275, height: 275,'.PHP_EOL;
 	    $outstr .= '         ranges: [{ startValue: -5, endValue:  0, style: { fill: \'#3399FF\', stroke: \'#3399FF\' }, endWidth: 10, startWidth: 10 },'.PHP_EOL;
@@ -167,7 +167,7 @@
 	    $outstr .= '       });'.PHP_EOL;
 	}
 
-	if ("$chiller_state" == "OK") {
+	if ("$chiller_state" == "YES") {
 	    $outstr .= '       $(\'#gaugeContainer_chiller'.$unr.'\').jqxGauge({'.PHP_EOL;
 	    $outstr .= '         min: -20, max: 25, width: 150, height: 150,'.PHP_EOL;
 	    $outstr .= '         ranges: [{ startValue: -20, endValue:  0, startWidth: 5, endWidth: 5, style: { fill: \'#3399FF\', stroke: \'#3399FF\' }},'.PHP_EOL;
@@ -184,15 +184,15 @@
 
 	$outstr .= '       setInterval(function(){'.PHP_EOL;
 	$outstr .= '         $.getJSON("getstate.php?uuid='.$unit.'", function(data) {'.PHP_EOL;
-	if ("$air_state" == "OK") {
+	if ("$air_state" == "YES") {
 	    $outstr .= '           $("#load_air_'.$unr.'").html(data.air_temperature);'.PHP_EOL;
 	    $outstr .= '           $("#gaugeContainer_air'.$unr.'").jqxGauge(\'value\', data.air_temperature);'.PHP_EOL;
 	}
-	if ("$beer_state" == "OK") {
+	if ("$beer_state" == "YES") {
 	    $outstr .= '           $("#load_beer_'.$unr.'").html(data.beer_temperature);'.PHP_EOL;
 	    $outstr .= '           $("#gaugeContainer_beer'.$unr.'").jqxGauge(\'value\', data.beer_temperature);'.PHP_EOL;
 	}
-	if ("$chiller_state" == "OK") {
+	if ("$chiller_state" == "YES") {
 	    $outstr .= '           $("#gaugeContainer_chiller'.$unr.'").jqxGauge(\'value\', data.chiller_temperature);'.PHP_EOL;
 	}
 	$outstr .= '           $("#load_target_lo_'.$unr.'").html(data.target_temperature_lo);'.PHP_EOL;
@@ -230,14 +230,14 @@
 
 	$outstr .= '    <div id="fermentor">'.PHP_EOL;
 	$outstr .= '     <div id="fermentor_thermometers">'.PHP_EOL;
-	if (("$air_state" == "OK") && ("$beer_state" == "OK") && ("$chiller_state" == "OK")) {
+	if (("$air_state" == "YES") && ("$beer_state" == "YES") && ("$chiller_state" == "YES")) {
 	    $outstr .= '       <div id="gaugeContainer_air'.$unr.'" style="float: left; margin-top: 10px; margin-left: 10px;"></div>'.PHP_EOL;
 	    $outstr .= '       <div id="gaugeContainer_beer'.$unr.'" style="float: right; margin-top: 10px; margin-right: 10px;"></div>'.PHP_EOL;
 	    $outstr .= '       <div id="gaugeContainer_chiller'.$unr.'" style="float: left; margin-top: 200px;"></div>'.PHP_EOL;
-	} else if (("$air_state" == "OK") && ("$beer_state" == "OK")) {
+	} else if (("$air_state" == "YES") && ("$beer_state" == "YES")) {
 	    $outstr .= '       <div id="gaugeContainer_air'.$unr.'" style="float: left; margin-top: 48px; margin-left: 48px;"></div>'.PHP_EOL;
 	    $outstr .= '       <div id="gaugeContainer_beer'.$unr.'" style="float: right; margin-top: 48px; margin-right: 48px;"></div>'.PHP_EOL;
-	} else if ("$air_state" == "OK") {
+	} else if ("$air_state" == "YES") {
 	    $outstr .= '       <div id="gaugeContainer_air'.$unr.'" style="margin-top: 48px; margin-left: 222px;"></div>'.PHP_EOL;
 	}
 	$outstr .= '     </div>'.PHP_EOL;
--- a/www/js/fermenter.js	Sat Apr 20 11:48:20 2024 +0200
+++ b/www/js/fermenter.js	Mon Apr 22 11:33:04 2024 +0200
@@ -96,8 +96,15 @@
    { name: 'os' },
    { name: 'os_version' },
    { name: 'FW' },
-   { name: 'room_temp', map: 'THB>temperature', type: 'float' },
-   { name: 'room_hum', map: 'THB>humidity', type: 'float' }
+   { name: 'server_port', type: 'int' },
+   { name: 'websocket_port', type: 'int' },
+   { name: 'thb_temp_uuid', map: 'THB>temperature>uuid' },
+   { name: 'temp_uuid', map: 'THB>temperature>uuid' },
+   { name: 'temp_state', map: 'THB>temperature>state' },
+   { name: 'temp_value', map: 'THB>temperature>value', type: 'int' },
+   { name: 'hum_uuid', map: 'THB>humidity>uuid' },
+   { name: 'hum_state', map: 'THB>humidity>state' },
+   { name: 'hum_value', map: 'THB>humidity>value', type: 'int' }
   ],
   id: 'name',
   url: 'getglobal.php'
@@ -162,7 +169,7 @@
  });
 
  function updateScreen() {
-   $('#room_thb').html(global.room_temp + '&deg;C&nbsp;&nbsp;' + global.room_hum + '% humidity');
+   $('#room_thb').html((global.temp_value / 1000.0) + '&deg;C&nbsp;&nbsp;' + (global.hum_value / 1000.0) + '% humidity');
    $('#info_system').html(record.unit);
    $('#info_beer').html(record.beercode + ' - ' + record.beername);
    $('#info_mode').jqxDropDownList('selectItem', record.mode);
@@ -284,7 +291,7 @@
     $('#gaugeContainer_air').jqxGauge({ caption: { value: 'Air: ' + record.air_temperature.toFixed(3) }});
     $('#gaugeContainer_air').jqxGauge({ value: record.air_temperature });
    }
-   if (record.air_state == 'OK') {
+   if (record.air_state == 'YES') {
     $('#gaugeContainer_air').jqxGauge({ disabled: false });
    } else {
     $('#gaugeContainer_air').jqxGauge({ disabled: true });
@@ -293,7 +300,7 @@
     $('#gaugeContainer_beer').jqxGauge({ caption: { value: 'Beer: ' + record.beer_temperature.toFixed(3) }});
     $('#gaugeContainer_beer').jqxGauge({ value: record.beer_temperature });
    }
-   if (record.beer_state == 'OK') {
+   if (record.beer_state == 'YES') {
     $('#gaugeContainer_beer').jqxGauge({ disabled: false });
    } else {
     $('#gaugeContainer_beer').jqxGauge({ disabled: true });
@@ -301,7 +308,7 @@
    if (record.chiller_temperature !== undefined) {
     $('#gaugeContainer_chiller').jqxGauge({ value: record.chiller_temperature });
    }
-   if (record.chiller_state == 'OK') {
+   if (record.chiller_state == 'YES') {
     $('#gaugeContainer_chiller').jqxGauge({ disabled: false });
    } else {
     $('#gaugeContainer_chiller').jqxGauge({ disabled: true });

mercurial