Fixed missing co2meters websocket data. Added websockets and removed polling for the mon-ispindel screen. The iSpindel SG gauge adjusts the resolution to the highest detected OG.

Tue, 19 May 2020 13:50:14 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 19 May 2020 13:50:14 +0200
changeset 680
0bb48333d133
parent 679
48f8f3fce7c0
child 681
7ed5c380e21b

Fixed missing co2meters websocket data. Added websockets and removed polling for the mon-ispindel screen. The iSpindel SG gauge adjusts the resolution to the highest detected OG.

bmsd/Makefile file | annotate | diff | comparison | revisions
bmsd/bms.c file | annotate | diff | comparison | revisions
bmsd/bms.h file | annotate | diff | comparison | revisions
bmsd/co2meters.c file | annotate | diff | comparison | revisions
bmsd/ispindels.c file | annotate | diff | comparison | revisions
bmsd/ispindels.h file | annotate | diff | comparison | revisions
bmsd/mysql.c file | annotate | diff | comparison | revisions
bmsd/mysql.h file | annotate | diff | comparison | revisions
bmsd/websocket.c file | annotate | diff | comparison | revisions
www/Makefile file | annotate | diff | comparison | revisions
www/cmd_ispindel.php file | annotate | diff | comparison | revisions
www/js/mon_co2meter.js file | annotate | diff | comparison | revisions
www/js/mon_ispindel.js file | annotate | diff | comparison | revisions
--- a/bmsd/Makefile	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/Makefile	Tue May 19 13:50:14 2020 +0200
@@ -66,5 +66,5 @@
 xutil.o: bms.h xutil.h
 rdconfig.o: bms.h xutil.h futil.h rdconfig.h
 mysql.o: bms.h xutil.h mysql.h nodes.h
-websocket.o: bms.h xutil.h websocket.h fermenters.h co2meters.h
+websocket.o: bms.h xutil.h websocket.h fermenters.h co2meters.h ispindels.h
 # End of generated dependencies
--- a/bmsd/bms.c	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/bms.c	Tue May 19 13:50:14 2020 +0200
@@ -146,9 +146,7 @@
 
 	usleep(3000000);
 	nodes_check_online();
-	usleep(1000000);
-	ispindel_mysql_check();
-	usleep(1000000);
+	usleep(2000000);
 	ws_check();
     }
     if (debug)
--- a/bmsd/bms.h	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/bms.h	Tue May 19 13:50:14 2020 +0200
@@ -323,8 +323,9 @@
     float			angle;			///< Tilt angle in degrees
     float			temperature;		///< Temperature in C
     float			battery;		///< Battery voltage
-    float			gravity;		///< Gravity in plato?
+    float			gravity;		///< Gravity in Plato
     int				interval;		///< Measure interval
+    float			og_gravity;		///< OG gravity in Plato detected
 } sys_ispindel_list;
 
 
--- a/bmsd/co2meters.c	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/co2meters.c	Tue May 19 13:50:14 2020 +0200
@@ -52,14 +52,22 @@
     msg = xstrcat(msg, co2meter->online ? (char *)"1":(char *)"0");
     msg = xstrcat(msg, (char *)",\"mode\":\"");
     msg = xstrcat(msg, co2meter->mode);
+    msg = xstrcat(msg, (char *)"\",\"beeruuid\":\"");
+    msg = xstrcat(msg, co2meter->beeruuid);
     msg = xstrcat(msg, (char *)"\",\"beercode\":\"");
     msg = xstrcat(msg, co2meter->beercode);
     msg = xstrcat(msg, (char *)"\",\"beername\":\"");
     msg = xstrcat(msg, co2meter->beername);
+    msg = xstrcat(msg, (char *)"\",\"temperature_state\":\"");
+    msg = xstrcat(msg, co2meter->temperature_state);
+    msg = xstrcat(msg, (char *)"\",\"temperature_address\":\"");
+    msg = xstrcat(msg, co2meter->temperature_address);
     msg = xstrcat(msg, (char *)"\",\"temperature\":");
     snprintf(buf, 64, "%.3f", co2meter->temperature);
     msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)",\"pressure_channel\":");
+    msg = xstrcat(msg, (char *)",\"pressure_state\":\"");
+    msg = xstrcat(msg, co2meter->pressure_state);
+    msg = xstrcat(msg, (char *)"\",\"pressure_channel\":");
     snprintf(buf, 64, "%d", co2meter->pressure_channel);
     msg = xstrcat(msg, buf);
     msg = xstrcat(msg, (char *)",\"pressure_voltage\":");
@@ -78,7 +86,6 @@
     ws_broadcast(msg);
     free(msg);
     msg = NULL;
-
 }
 
 
--- a/bmsd/ispindels.c	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/ispindels.c	Tue May 19 13:50:14 2020 +0200
@@ -40,19 +40,177 @@
 extern MYSQL_ROW	row;
 
 
+void ispindel_ws_send(sys_ispindel_list *ispindel)
+{
+    char	*msg = NULL, buf[65];
+
+    msg = xstrcpy((char *)"{\"device\":\"ispindels\",\"node\":\"");
+    msg = xstrcat(msg, ispindel->node);
+    msg = xstrcat(msg, (char *)"\",\"unit\":\"");
+    msg = xstrcat(msg, ispindel->alias);
+    msg = xstrcat(msg, (char *)"\",\"online\":");
+    msg = xstrcat(msg, ispindel->online ? (char *)"1":(char *)"0");
+    msg = xstrcat(msg, (char *)",\"mode\":\"");
+    msg = xstrcat(msg, ispindel->mode);
+    msg = xstrcat(msg, (char *)"\",\"beeruuid\":\"");
+    msg = xstrcat(msg, ispindel->beeruuid);
+    msg = xstrcat(msg, (char *)"\",\"beercode\":\"");
+    msg = xstrcat(msg, ispindel->beercode);
+    msg = xstrcat(msg, (char *)"\",\"beername\":\"");
+    msg = xstrcat(msg, ispindel->beername);
+    msg = xstrcat(msg, (char *)"\",\"temperature\":");
+    snprintf(buf, 64, "%.4f", ispindel->temperature);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)",\"angle\":");
+    snprintf(buf, 64, "%.6f", ispindel->angle);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)",\"battery\":");
+    snprintf(buf, 64, "%.6f", ispindel->battery);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)",\"gravity\":");
+    snprintf(buf, 64, "%.6f", ispindel->gravity);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)",\"og_gravity\":");
+    snprintf(buf, 64, "%.6f", ispindel->og_gravity);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)",\"alarm\":");
+    snprintf(buf, 64, "%d", ispindel->alarm);
+    msg = xstrcat(msg, buf);
+    msg = xstrcat(msg, (char *)"}");
+    ws_broadcast(msg);
+    free(msg);
+    msg = NULL;
+}
+
+
+
+void ispindel_ws_receive(char *payload)
+{
+    struct json_object  *jobj, *val;
+    sys_ispindel_list   *tmpp;
+    char                *node = NULL, *alias = NULL, *mode = NULL, *beeruuid = NULL, *beercode = NULL, *beername = NULL;
+    char                query[512], *end;
+    MYSQL               *con2 = NULL;
+
+//    syslog(LOG_NOTICE, "ispindel_ws_receive(%s)", payload);
+
+    /*
+     * Process the JSON formatted payload.
+     */
+    jobj = json_tokener_parse(payload);
+    if (json_object_object_get_ex(jobj, "node", &val))
+        node = xstrcpy((char *)json_object_get_string(val));
+    if (json_object_object_get_ex(jobj, "unit", &val))
+        alias = xstrcpy((char *)json_object_get_string(val));
+    if (json_object_object_get_ex(jobj, "beeruuid", &val))
+        beeruuid = xstrcpy((char *)json_object_get_string(val));
+    if (json_object_object_get_ex(jobj, "beercode", &val))
+        beercode = xstrcpy((char *)json_object_get_string(val));
+    if (json_object_object_get_ex(jobj, "beername", &val))
+        beername = xstrcpy((char *)json_object_get_string(val));
+    if (json_object_object_get_ex(jobj, "mode", &val))
+	mode = xstrcpy((char *)json_object_get_string(val));
+    json_object_put(jobj);
+
+    /*
+     * Search ispindel record in the memory array and use it if found.
+     */
+    if (ispindels) {
+        for (tmpp = ispindels; tmpp; tmpp = tmpp->next) {
+            if (strcmp(tmpp->node, node) == 0) {
+		con2 = mysql_init(NULL);
+                if (con2 == NULL) {
+                    syslog(LOG_NOTICE, "MySQL: mysql_init() failed");
+                } else {
+                    if (mysql_real_connect(con2, Config.mysql_host, Config.mysql_user, Config.mysql_pass, Config.mysql_database, Config.mysql_port, NULL, 0) == NULL) {
+                        syslog(LOG_NOTICE, "MySQL: mysql_real_connect() %s", mysql_error(con2));
+                    } else {
+			if (beeruuid && beercode && beername) {
+			    end = stpcpy(query, "UPDATE mon_ispindels SET beeruuid='");
+                            end += mysql_real_escape_string(con2, end, beeruuid, strlen(beeruuid));
+                            end = stpcpy(end, "', beercode='");
+                            end += mysql_real_escape_string(con2, end, beercode, strlen(beercode));
+                            end = stpcpy(end, "', beername='");
+                            end += mysql_real_escape_string(con2, end, beername, strlen(beername));
+                            end = stpcpy(end, "', og_gravity='0.0' WHERE node='");
+                            end += mysql_real_escape_string(con2, end, node, strlen(node));
+                            end = stpcpy(end, "'");
+
+			    if (mysql_real_query(con2, query, (unsigned int) (end - query))) {
+                                syslog(LOG_NOTICE, "MySQL: `%s' error %u (%s))", query, mysql_errno(con2), mysql_error(con2));
+                            } else {
+                                /* Database updated, now update internal memory */
+                                syslog(LOG_NOTICE, "MySQL: `%s' Ok", query);
+                                if (tmpp->beercode)
+                                    free(tmpp->beercode);
+                                tmpp->beercode = xstrcpy(beercode);
+                                if (tmpp->beername)
+                                    free(tmpp->beername);
+                                tmpp->beername = xstrcpy(beername);
+                                if (tmpp->beeruuid)
+                                    free(tmpp->beeruuid);
+                                tmpp->beeruuid = xstrcpy(beeruuid);
+				tmpp->og_gravity = 0.0;
+                                /* Report new state to the client */
+                                ispindel_ws_send(tmpp);
+                                syslog(LOG_NOTICE, "Set ispindel %s/%s new beer %s %s", node, alias, beercode, beername);
+			    }
+			}
+			if (mode) {
+			    end = stpcpy(query, "UPDATE mon_ispindels SET mode='");
+                            end += mysql_real_escape_string(con2, end, mode, strlen(mode));
+                            end = stpcpy(end, "' WHERE node='");
+                            end += mysql_real_escape_string(con2, end, node, strlen(node));
+                            end = stpcpy(end, "'");
+
+			    if (mysql_real_query(con2, query, (unsigned int) (end - query))) {
+                                syslog(LOG_NOTICE, "MySQL: `%s' error %u (%s))", query, mysql_errno(con2), mysql_error(con2));
+                            } else {
+                                /* Database updated, now update internal memory */
+                                syslog(LOG_NOTICE, "MySQL: `%s' Ok", query);
+                                if (tmpp->mode)
+                                    free(tmpp->mode);
+                                tmpp->mode = xstrcpy(mode);
+                                /* Report new state to the client */
+                                ispindel_ws_send(tmpp);
+                                syslog(LOG_NOTICE, "Set ispindel %s/%s new mode %s", node, alias, mode);
+                            }
+			}
+			mysql_close(con2);
+		    }
+		}
+		break;
+            }
+        }
+    }
+
+    if (node)
+        free(node);
+    if (alias)
+        free(alias);
+    if (mode)
+	free(mode);
+    if (beeruuid)
+        free(beeruuid);
+    if (beercode)
+        free(beercode);
+    if (beername)
+        free(beername);
+}
+
+
 
 void ispindel_set(char *node, char *payload)
 {
     sys_ispindel_list	*ispindel, *tmpp;
     struct json_object  *jobj, *metric, *val;
     bool		new_ispindel = true;
-    char		*datetime, buf[65], *line, *logfile, *msg = NULL;
+    char		*datetime, buf[65], *line, *logfile;
     struct tm           *mytime;
     time_t              timestamp;
     FILE		*fp;
 
-//    if (debug)
-//    	printf("ispindel_set: %s %s\n", node, payload);
+    // syslog(LOG_NOTICE, "ispindel_set: %s %s", node, payload);
 
     /*
      * Search ispindel record in the memory array and use it if found.
@@ -102,55 +260,25 @@
                 free(ispindel->alias);
             ispindel->alias = xstrcpy((char *)json_object_get_string(val));
         }
-	if (json_object_object_get_ex(metric, "alarm", &val)) {
+	if (json_object_object_get_ex(metric, "alarm", &val))
             ispindel->alarm = json_object_get_int(val);
-        }
-	if (json_object_object_get_ex(metric, "interval", &val)) {
+	if (json_object_object_get_ex(metric, "interval", &val))
             ispindel->interval = json_object_get_int(val);
-        }
-	if (json_object_object_get_ex(metric, "angle", &val)) {
+	if (json_object_object_get_ex(metric, "angle", &val))
             ispindel->angle = json_object_get_double(val);
-        }
-	if (json_object_object_get_ex(metric, "temperature", &val)) {
+	if (json_object_object_get_ex(metric, "temperature", &val))
             ispindel->temperature = json_object_get_double(val);
-        }
-	if (json_object_object_get_ex(metric, "battery", &val)) {
+	if (json_object_object_get_ex(metric, "battery", &val))
             ispindel->battery = json_object_get_double(val);
-        }
 	if (json_object_object_get_ex(metric, "gravity", &val)) {
             ispindel->gravity = json_object_get_double(val);
+	    if (ispindel->gravity > ispindel->og_gravity)
+		ispindel->og_gravity = ispindel->gravity;
         }
     }
 
-    msg = xstrcpy((char *)"{\"device\":\"ispindels\",\"node\":\"");
-    msg = xstrcat(msg, node);
-    msg = xstrcat(msg, (char *)"\",\"unit\":\"");
-    msg = xstrcat(msg, ispindel->alias);
-    msg = xstrcat(msg, (char *)"\",\"online\":");
-    msg = xstrcat(msg, ispindel->online ? (char *)"1":(char *)"0");
-    msg = xstrcat(msg, (char *)",\"mode\":\"");
-    msg = xstrcat(msg, ispindel->mode);
-    msg = xstrcat(msg, (char *)"\",\"temperature\":");
-    snprintf(buf, 64, "%.4f", ispindel->temperature);
-    msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)",\"angle\":");
-    snprintf(buf, 64, "%.5f", ispindel->angle);
-    msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)",\"battery\":");
-    snprintf(buf, 64, "%.6f", ispindel->battery);
-    msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)",\"gravity\":");
-    snprintf(buf, 64, "%.5f", ispindel->gravity);
-    msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)",\"alarm\":");
-    snprintf(buf, 64, "%d", ispindel->alarm);
-    msg = xstrcat(msg, buf);
-    msg = xstrcat(msg, (char *)"}");
-    ws_broadcast(msg);
-    free(msg);
-    msg = NULL;
+//    ispindel_dump(ispindel);
 
-//    ispindel_dump(ispindel);
 
     if (new_ispindel) {
     	if (ispindels == NULL) {
@@ -167,6 +295,7 @@
     } else {
 	ispindel_mysql_update(ispindel);
     }
+    ispindel_ws_send(ispindel);
 
     /*
      * The data is complete, see if we can write a log entry.
@@ -187,7 +316,6 @@
 	snprintf(buf, 64, "%.5f", ispindel->gravity);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
-//	snprintf(buf, 64, "%.5f", 1 + (ispindel->gravity / (258.6 - ((ispindel->gravity / 258.2) * 227.1))));
 	snprintf(buf, 64, "%.5f", 1.00001 + (0.0038661 * ispindel->gravity) + (1.3488e-5 * ispindel->gravity * ispindel->gravity) +
 			(4.3074e-8 * ispindel->gravity * ispindel->gravity * ispindel->gravity));
 	line = xstrcat(line, buf);
@@ -264,6 +392,7 @@
 	printf("battery     %.6f\n", ispindel->battery);
 	printf("gravity     %.5f\n", ispindel->gravity);
 	printf("interval    %d\n", ispindel->interval);
+	printf("og_gravity  %.5f\n", ispindel->og_gravity);
     }
 }
 
--- a/bmsd/ispindels.h	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/ispindels.h	Tue May 19 13:50:14 2020 +0200
@@ -8,6 +8,12 @@
 void ispindel_dump(sys_ispindel_list *ispindel);
 
 /**
+ * @brief Process received command from a websocket.
+ * @param payload The received data in JSON format.
+ */
+void ispindel_ws_receive(char *payload);
+
+/**
  * @brief Messages received from a iSpindel using the MQTT sender.
  *        A new node is created if this is the first message of the
  *        iSpindel, else the last seen time is updated. Then the last
--- a/bmsd/mysql.c	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/mysql.c	Tue May 19 13:50:14 2020 +0200
@@ -300,6 +300,7 @@
 		ispindel->gravity             = atof(row[12]);
 		ispindel->interval            = atoi(row[13]);
 		ispindel->mode		      = xstrcpy(row[14]);
+		ispindel->og_gravity	      = atof(row[15]);
 
                 if (ispindels == NULL) {
                     ispindels = ispindel;
@@ -317,7 +318,7 @@
         }
     }
 
-    syslog(LOG_NOTICE, "MySQL: loaded %d nodes, %d fermenters, %d co2meters %d ispindels", ncnt, fcnt, ccnt, icnt);
+    syslog(LOG_NOTICE, "MySQL: loaded %d nodes, %d fermenters, %d co2meters, %d ispindels", ncnt, fcnt, ccnt, icnt);
     return 0;
 }
 
@@ -729,7 +730,7 @@
 
     snprintf(query, 2559,
         "INSERT INTO mon_ispindels SET uuid='%s', alias='%s', node='%s', online='%d', mode='%s', alarm='%d', " \
-        "angle='%.5f', temperature='%.4f', battery='%.6f', gravity='%.5f', up_interval='%d', og_gravity='0.0'",
+        "angle='%.6f', temperature='%.4f', battery='%.6f', gravity='%.6f', up_interval='%d', og_gravity='0.0'",
         ispindel->uuid, ispindel->alias, ispindel->node, ispindel->online ? 1:0, ispindel->mode, ispindel->alarm,
         ispindel->angle, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval);
 
@@ -746,11 +747,10 @@
     char        *query = malloc(2560);
 
     snprintf(query, 2559,
-        "UPDATE mon_ispindels SET online='%d', mode='%s', alarm='%d', " \
-	"angle='%.5f', temperature='%.4f', battery='%.6f', gravity='%.5f', up_interval='%d', og_gravity=GREATEST(og_gravity, '%.5f') WHERE uuid='%s'",
-        ispindel->online ? 1:0, ispindel->mode, ispindel->alarm,
+        "UPDATE mon_ispindels SET online='%d', mode='%s', alias='%s', alarm='%d', " \
+	"angle='%.6f', temperature='%.4f', battery='%.6f', gravity='%.6f', up_interval='%d', og_gravity=GREATEST(og_gravity, '%.6f') WHERE uuid='%s'",
+        ispindel->online ? 1:0, ispindel->mode, ispindel->alias, ispindel->alarm,
 	ispindel->angle, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval, ispindel->gravity, ispindel->uuid);
-
     bms_mysql_query(query);
     free(query);
 }
@@ -766,67 +766,3 @@
     free(query);
 }
 
-
-
-/*
- * Check using a new MySQL connection because we are running from another thread.
- */
-void ispindel_mysql_check(void)
-{
-    sys_ispindel_list	*tmpp;
-    MYSQL		*con2 = NULL;
-    MYSQL_RES		*res_set2;
-    MYSQL_ROW		row2;
-
-    if (ispindels == NULL)
-	return;
-
-    con2 = mysql_init(NULL);
-    if (con2 == NULL) {
-        syslog(LOG_NOTICE, "MySQL: mysql_init() failed");
-        return;
-    }
-
-    if (mysql_real_connect(con2, Config.mysql_host, Config.mysql_user, Config.mysql_pass, Config.mysql_database, Config.mysql_port, NULL, 0) == NULL) {
-        syslog(LOG_NOTICE, "MySQL: mysql_real_connect() %s", mysql_error(con2));
-        return;
-    }
-
-    if (mysql_query(con2, "SELECT uuid,alias,beercode,beername,beeruuid,mode FROM mon_ispindels;")) {
-        syslog(LOG_NOTICE, "MySQL: SELECT uuid,alias,beercode,beername,beeruuid,mode FROM mon_ispindels error %u (%s))", mysql_errno(con2), mysql_error(con2));
-    } else {
-        res_set2 = mysql_store_result(con2);
-        if (res_set2 == NULL) {
-            syslog(LOG_NOTICE, "MySQL: mysq_store_result error %u (%s))", mysql_errno(con2), mysql_error(con2));
-        } else {
-            while ((row2 = mysql_fetch_row(res_set2)) != NULL) {
-		for (tmpp = ispindels; tmpp; tmpp = tmpp->next) {
-		    if (strcmp(tmpp->uuid, row2[0]) == 0) {
-			if (strcmp(tmpp->beercode, row2[2]) || strcmp(tmpp->beername, row2[3]) || strcmp(tmpp->beeruuid, row2[4])) {
-			    syslog(LOG_NOTICE, "ispindel `%s` change beer to `%s %s`", row2[1], row2[2], row2[3]);
-			    if (tmpp->beercode)
-				free(tmpp->beercode);
-			    tmpp->beercode = xstrcpy(row2[2]);
-			    if (tmpp->beername)
-				free(tmpp->beername);
-			    tmpp->beername = xstrcpy(row2[3]);
-			    if (tmpp->beeruuid)
-				free(tmpp->beeruuid);
-			    tmpp->beeruuid = xstrcpy(row2[4]);
-			}
-			if (strcmp(tmpp->mode, row2[5])) {
-			    syslog(LOG_NOTICE, "ispindel `%s` change mode `%s`", row2[1], row2[5]);
-			    if (tmpp->mode)
-				free(tmpp->mode);
-			    tmpp->mode = xstrcpy(row2[5]);
-			}
-		    }
-		}
-	    }
-	    mysql_free_result(res_set2);
-	}
-    }
-
-    mysql_close(con2);
-}
-
--- a/bmsd/mysql.h	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/mysql.h	Tue May 19 13:50:14 2020 +0200
@@ -45,12 +45,5 @@
 void ispindel_mysql_update(sys_ispindel_list *ispindel);
 void ispindel_mysql_death(char *alias);
 
-/**
- * @brief Check state changes in the database for all iSpindels and
- *        update the internal memory array. Called every 5 seconds from
- *        the main server thread.
- */
-void ispindel_mysql_check(void);
-
 
 #endif
--- a/bmsd/websocket.c	Mon May 18 11:00:59 2020 +0200
+++ b/bmsd/websocket.c	Tue May 19 13:50:14 2020 +0200
@@ -29,6 +29,7 @@
 #include "websocket.h"
 #include "fermenters.h"
 #include "co2meters.h"
+#include "ispindels.h"
 #include <libwebsockets.h>
 
 
@@ -124,6 +125,8 @@
 		    fermenter_ws_receive(buf);
 		} else if (strncmp(buf, (char *)"{\"device\":\"co2meters\",", 22) == 0) {
 		    co2meter_ws_receive(buf);
+		} else if (strncmp(buf, (char *)"{\"device\":\"ispindels\",", 22) == 0) {
+		    ispindel_ws_receive(buf);
 		}
 
                 break;
--- a/www/Makefile	Mon May 18 11:00:59 2020 +0200
+++ b/www/Makefile	Tue May 19 13:50:14 2020 +0200
@@ -3,7 +3,7 @@
 
 include ../Makefile.global
 
-SRC		= cmd_ispindel.php config.php.dist crontasks.php \
+SRC		= config.php.dist crontasks.php \
 		  export_equipments.php export_fermentables.php export_hops.php export_mashs.php \
 		  export_miscs.php export_styles.php export_suppliers.php export_waters.php \
 		  export_yeasts.php favicon.ico gen_about.php \
--- a/www/cmd_ispindel.php	Mon May 18 11:00:59 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-<?php
-require_once('config.php');
-
-#Connect to the database
-$connect = mysqli_connect(DBASE_HOST, DBASE_USER, DBASE_PASS, DBASE_NAME);
-if (! $connect) {
-        die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
-}
-mysqli_set_charset($connect, "utf8" );
-$sql = "";
-
-if (isset($_POST['beername']) && isset($_POST['beercode']) && isset($_POST['beeruuid'])) {
-	$sql  = "UPDATE `mon_ispindels` SET ";
-	$sql .=    "beername='" . mysqli_real_escape_string($connect, $_POST['beername']);
-	$sql .= "', beercode='" . mysqli_real_escape_string($connect, $_POST['beercode']);
-	$sql .= "', beeruuid='" . mysqli_real_escape_string($connect, $_POST['beeruuid']);
-	$sql .= "', og_gravity=0 WHERE uuid='" . $_POST['uuid'] . "';";
-} else if (isset($_POST['mode'])) {
-	$sql  = "UPDATE `mon_ispindels` SET mode='" .$_POST['mode'] . "' WHERE uuid='" . $_POST['uuid'] . "';";
-} else {
-	syslog(LOG_NOTICE, "cmd_ispindel: unknown POST");
-}
-
-$result = mysqli_query($connect, $sql);
-if (! $result) {
-	syslog(LOG_NOTICE, "cmd_ispindel: result: ".mysqli_error($connect));
-}
-echo $result;
-?>
--- a/www/js/mon_co2meter.js	Mon May 18 11:00:59 2020 +0200
+++ b/www/js/mon_co2meter.js	Tue May 19 13:50:14 2020 +0200
@@ -51,9 +51,7 @@
    }
    return data;
   },
-  loadError: function(jqXHR, status, error) {
-   $('#err').text(status + ' ' + error);
-  },
+  loadError: function(jqXHR, status, error) { console.log(status + ' ' + error); },
  }),
  gaugeoptionst = {
   min: 10, max: 40, width: 375, height: 375,
@@ -93,8 +91,12 @@
    { name: 'mode', type: 'string' },
    { name: 'alarm', type: 'int' },
    { name: 'temperature_state', type: 'string' },
+   { name: 'temperature_address', type: 'string' },
    { name: 'temperature', type: 'float' },
    { name: 'pressure_state', type: 'string' },
+   { name: 'pressure_channel', type: 'int' },
+   { name: 'pressure_voltage', type: 'float' },
+   { name: 'pressure_zero', type: 'float' },
    { name: 'pressure_bar', type: 'float' }
   ],
   id: 'record',
@@ -103,15 +105,20 @@
  dataAdapter = new $.jqx.dataAdapter(source, {
   loadComplete: function(records) {
    record = dataAdapter.records[0];
+   updateScreen();
+   blank['name'] = record.alias;
+   blank['code'] = record.alias.toUpperCase();
+   blank['uuid'] = record.uuid;
+  }
+ });
+
+ function updateScreen() {
    var oline = (record.online) ? 'On-line' : 'Off-line';
    $('#info_uuid').html(record.uuid);
    $('#info_system').html(record.node + '/' + record.alias);
    $('#info_online').html(oline);
    $('#info_beer').html(record.beercode + ' - ' + record.beername);
    $('#info_mode').html(record.mode);
-   blank['name'] = record.alias;
-   blank['code'] = record.alias.toUpperCase();
-   blank['uuid'] = record.uuid;
 
    if (record.online && (record.mode != 'OFF')) {
     $('#co2meter_powerled').html('<div class="LEDblue_on"></div>Power');
@@ -143,8 +150,7 @@
    } else {
     $('#gaugeContainer_pressure').jqxGauge({ disabled: true });
    }
-  }
- });
+ }
 
  $('#select_beer').jqxDropDownList({
   placeHolder: 'Kies bier:',
@@ -177,9 +183,8 @@
    record.beername = datarecord.name;
    record.beeruuid = datarecord.uuid;
    console.log('Select beer ' + record.beercode + ', ' + record.beername);
-   var msg = '{"device":"co2meters","node":"' + record.node + '","unit":"' + record.alias +
-             '","beeruuid":"' + record.beeruuid + '","beercode":"' + record.beercode + '","beername":"' + record.beername + '"}';
-   websocket.send(msg);
+   websocket.send('{"device":"co2meters","node":"' + record.node + '","unit":"' + record.alias +
+             '","beeruuid":"' + record.beeruuid + '","beercode":"' + record.beercode + '","beername":"' + record.beername + '"}');
   }
  });
 
@@ -194,34 +199,23 @@
   var obj = JSON.parse(msg);
   if (obj.device == "co2meters" && obj.node == record.node && obj.unit == record.alias) {
    console.log('ws got this device ' + msg);
+   record.online = obj.online;
    if (obj.online) {
-    $('#info_online').html('On-line');
-   } else {
-    $('#info_online').html('Off-line');
+    record.beeruuid = obj.beeruuid;
+    record.beercode = obj.beercode;
+    record.beername = obj.beername;
+    record.mode = obj.mode;
+    record.alarm = obj.alarm;
+    record.temperature_state = obj.temperature_state;
+    record.temperature_address = obj.temperature_address;
+    record.temperature = obj.temperature;
+    record.pressure_state = obj.pressure_state;
+    record.pressure_channel = obj.pressure_channel;
+    record.pressure_voltage = obj.pressure_voltage;
+    record.pressure_zero = obj.pressure_zero;
+    record.pressure_bar = obj.pressure_bar;
    }
-   $('#info_beer').html(obj.beercode + ' - ' + obj.beername);
-   $('#info_mode').html(obj.mode);
-   if (obj.online && obj.mode != 'OFF') {
-    $('#co2meter_powerled').html('<div class="LEDblue_on"></div>Power');
-    $('#select_beer').jqxDropDownList({ disabled: true });
-    $('#select_beer').jqxDropDownList('clearSelection');
-    $('#select_beer').hide();
-   } else {
-    $('#co2meter_powerled').html('<div class="LEDblue_off"></div>Power');
-    $('#select_beer').show();
-    $('#select_beer').jqxDropDownList({ disabled: false });
-   }
-   if (obj.online && (obj.alarm != '0')) {
-    $('#co2meter_alarmled').html('<div class="LEDred_on"></div>Alarm');
-   } else {
-    $('#co2meter_alarmled').html('<div class="LEDred_off"></div>Alarm');
-   }
-
-   $('#gaugeContainer_temperature').jqxGauge({ caption: { value: 'Temp: ' + obj.temperature.toFixed(3) }});
-   $('#gaugeContainer_temperature').jqxGauge({ value: obj.temperature });
-   $('#gaugeContainer_pressure').jqxGauge({ caption: { value: 'Bar: ' + obj.pressure_bar.toFixed(2) }});
-   $('#gaugeContainer_pressure').jqxGauge({ value: obj.pressure_bar });
-
+   updateScreen();
   }
   ws_global(msg);
  }
--- a/www/js/mon_ispindel.js	Mon May 18 11:00:59 2020 +0200
+++ b/www/js/mon_ispindel.js	Tue May 19 13:50:14 2020 +0200
@@ -25,9 +25,6 @@
 
  var record = {},
  blank = {},
- newProduct = false,
- newMode = false,
- schedule = 0,
 
  productSource = {
   datatype: 'json',
@@ -54,9 +51,7 @@
    }
    return data;
   },
-  loadError: function(jqXHR, status, error) {
-   $('#err').text(status + ' ' + error);
-  },
+  loadError: function(jqXHR, status, error) { console.log(status + ' ' + error); },
  }),
  gaugeoptionst = {
   min: 10, max: 40, width: 375, height: 375,
@@ -109,17 +104,23 @@
  dataAdapter = new $.jqx.dataAdapter(source, {
   loadComplete: function(records) {
    record = dataAdapter.records[0];
-   var oline = (record.online) ? 'On-line' : 'Off-line';
-   $('#info_uuid').html(record.uuid);
-   $('#info_system').html(record.node + '/' + record.alias);
-   $('#info_online').html(oline);
-   $('#info_beer').html(record.beercode + ' - ' + record.beername);
-   $('#info_mode').jqxDropDownList('selectItem', record.mode);
+   updateScreen();
    blank['name'] = record.alias;
    blank['code'] = record.alias.toUpperCase();
    blank['uuid'] = record.uuid;
+  }
+ });
 
-   if (record.online && (record.mode != 'OFF')) {
+ function updateScreen() {
+
+  $('#info_uuid').html(record.uuid);
+  $('#info_system').html(record.node + '/' + record.alias);
+  $('#info_beer').html(record.beercode + ' - ' + record.beername);
+  $('#info_mode').jqxDropDownList('selectItem', record.mode);
+
+  if (record.online) {
+   $('#info_online').html('On-line');
+   if (record.mode != 'OFF') {
     $('#ispindel_powerled').html('<div class="LEDblue_on"></div>Power');
     $('#select_beer').jqxDropDownList({ disabled: true });
     $('#select_beer').jqxDropDownList('clearSelection');
@@ -137,9 +138,10 @@
 
    $('#gaugeContainer_temperature').jqxGauge({ caption: { value: record.temperature.toFixed(3) + '°C' }});
    $('#gaugeContainer_temperature').jqxGauge({ value: record.temperature });
+   $('#gaugeContainer_temperature').jqxGauge({ disabled: false });
+  $('#gaugeContainer_gravity').jqxLinearGauge({ disabled: false });
 
    var sg = plato_to_sg(record.gravity);
-
    $('#info_battery').val(record.battery);
    $('#info_tilt').val(record.angle);
    $('#info_plato').val(record.gravity);
@@ -148,7 +150,10 @@
    if (record.og_gravity) {
     var og = plato_to_sg(record.og_gravity);
     var svg = calc_svg(og, sg);
+    var max = Math.ceil(og * 100, 0) * 10;
 
+    console.log ('set max ' + max);
+    $('#gaugeContainer_gravity').jqxLinearGauge({ max: max });
     $('#vg_og1').html(og.toFixed(4));
     $('#vg_og2').html(record.og_gravity.toFixed(1) + '&deg;P');
     $('#vg_sg1').html(sg.toFixed(4));
@@ -156,6 +161,7 @@
     $('#vg_svg').html(svg.toFixed(1) + '%');
     $('#vg_abv').html(abvol(og, sg).toFixed(2) + '%');
    } else {
+    $('#gaugeContainer_gravity').jqxLinearGauge({ max: 1150 });
     $('#vg_og1').html('');
     $('#vg_og2').html('');
     $('#vg_sg1').html('');
@@ -172,11 +178,19 @@
     batt = 100;
    $('#vg_batt').html(batt + '%');
 
-
    var gravity = sg * 1000;
    $('#gaugeContainer_gravity').jqxLinearGauge({ value: gravity });
+
+  } else { // offline
+   $('#info_online').html('Off-line');
+   $('#ispindel_powerled').html('<div class="LEDblue_off"></div>Power');
+   $('#select_beer').show();
+   $('#select_beer').jqxDropDownList({ disabled: false });
+   $('#ispindel_alarmled').html('<div class="LEDred_on"></div>Alarm');
+   $('#gaugeContainer_temperature').jqxGauge({ disabled: true });
+   $('#gaugeContainer_gravity').jqxLinearGauge({ disabled: true });
   }
- });
+ }
 
  $('#select_beer').jqxDropDownList({
   placeHolder: 'Kies bier:',
@@ -199,64 +213,14 @@
  $('#info_sg').jqxNumberInput(Show4dec);
 
  $('#gaugeContainer_temperature').jqxGauge(gaugeoptionst);
- $('#gaugeContainer_temperature').jqxGauge({ caption: { value: 'Temp: 00.000' }});
+ $('#gaugeContainer_temperature').jqxGauge({ caption: { value: '0.000°C' }});
  $('#gaugeContainer_gravity').jqxLinearGauge(gaugeoptionsg);
 
  srcMode = ['OFF', 'ON'];
  $('#info_mode').jqxDropDownList({ theme: theme, source: srcMode, width: 100, height: 24, dropDownHeight: 65 });
 
- function sendProduct(code, name, uuid) {
-
-  console.log('sendProduct(' + code + ', ' + name + ', ' + uuid + ')');
-  var data = 'uuid=' + record.uuid + '&beeruuid=' + uuid + '&beercode=' + code + '&beername=' + name;
-  $.ajax({
-   url: 'cmd_ispindel.php',
-   data: data,
-   type: 'POST',
-   success: function(data) {},
-   error: function(jqXHR, textStatus, errorThrown) { console.log('sendProduct() error'); }
-  });
- }
-
- function sendMode(mode) {
-
-  console.log('sendMode(' + mode + ')');
-  var data = 'uuid=' + record.uuid + '&mode=' + mode;
-  $.ajax({
-   url: 'cmd_ispindel.php',
-   data: data,
-   type: 'POST',
-   success: function(data) {},
-   error: function(jqXHR, textStatus, errorThrown) { console.log('sendMode() error'); }
-  });
- }
-
- // Get the data immediatly and then at regular intervals to refresh.
+ // Get the data immediatly.
  dataAdapter.dataBind();
- setInterval(function() {
-  var skip = false;
-  if (newMode) {
-   sendMode(record.mode);
-   newMode = false;
-   skip = true;
-  }
-  if (newProduct) {
-   sendProduct(record.beercode, record.beername, record.beeruuid);
-   newProduct = false;
-   skip = true;
-  }
-  if (skip) {
-   schedule = 4; // 2 seconds wait to get the results
-  } else {
-   if (schedule > 0)
-    schedule--;
-  }
-
-  if (schedule <= 0) {
-   dataAdapter.dataBind();
-   schedule = 20;
-  }
- }, 500);
 
  $('#select_beer').on('select', function(event) {
   if (event.args) {
@@ -265,13 +229,16 @@
    record.beercode = datarecord.code;
    record.beername = datarecord.name;
    record.beeruuid = datarecord.uuid;
-   newProduct = true;
+   console.log('Select beer ' + record.beercode + ', ' + record.beername);
+   websocket.send('{"device":"ispindels","node":"' + record.node + '","unit":"' + record.alias +
+             '","beeruuid":"' + record.beeruuid + '","beercode":"' + record.beercode + '","beername":"' + record.beername + '"}');
   }
  });
  $('#info_mode').on('select', function(event) {
-  if (event.args) {
+  if (event.args && event.args.item.value != record.mode) {
    record.mode = event.args.item.value;
-   newMode = true;
+   console.log('set mode ' + record.mode);
+   websocket.send('{"device":"ispindels","node":"' + record.node + '","unit":"' + record.alias + '","mode":"' + record.mode + '"}');
   }
  });
 
@@ -280,4 +247,28 @@
  $('#VLog').click(function() {
   window.open('log_ispindel.php?code=' + record.beercode + '&name=' + record.beername);
  });
+
+ websocket.onmessage = function(evt) {
+  var msg = evt.data;
+  var obj = JSON.parse(msg);
+  if (obj.device == "ispindels" && obj.node == record.node) {
+   console.log('ws got this device ' + msg);
+   record.online = obj.online;
+   if (obj.online) {
+    record.beeruuid = obj.beeruuid;
+    record.beercode = obj.beercode;
+    record.beername = obj.beername;
+    record.mode = obj.mode;
+    record.alarm = obj.alarm;
+    record.angle = obj.angle;
+    record.temperature = obj.temperature;
+    record.battery = obj.battery;
+    record.gravity = obj.gravity;
+    record.up_interval = obj.up_interval;
+    record.og_gravity = obj.og_gravity;
+   }
+   updateScreen();
+  }
+  ws_global(msg);
+ }
 });

mercurial