Changed the interface from the iSpindels to be the same as other devices. A webpage converts each call to two standard MQTT messages. The nodes MQTT message extended with an interval parameter. iSpindels now have a generated uuid made up from the chipid.

Sun, 05 Jan 2020 11:42:02 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 05 Jan 2020 11:42:02 +0100
changeset 578
e75ce5bbda73
parent 577
b4bfed3684d0
child 579
1253a237b620

Changed the interface from the iSpindels to be the same as other devices. A webpage converts each call to two standard MQTT messages. The nodes MQTT message extended with an interval parameter. iSpindels now have a generated uuid made up from the chipid.

bmsd/bms.h file | annotate | diff | comparison | revisions
bmsd/ispindels.c file | annotate | diff | comparison | revisions
bmsd/ispindels.h file | annotate | diff | comparison | revisions
bmsd/mqtt.c file | annotate | diff | comparison | revisions
bmsd/mysql.c file | annotate | diff | comparison | revisions
bmsd/nodes.c file | annotate | diff | comparison | revisions
www/Makefile file | annotate | diff | comparison | revisions
www/cmd_ispindel.php file | annotate | diff | comparison | revisions
www/getispindel.php file | annotate | diff | comparison | revisions
www/includes/global.inc.php file | annotate | diff | comparison | revisions
www/js/mon_ispindel.js file | annotate | diff | comparison | revisions
www/js/mon_node.js file | annotate | diff | comparison | revisions
www/mon_ispindel.php file | annotate | diff | comparison | revisions
--- a/bmsd/bms.h	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/bms.h	Sun Jan 05 11:42:02 2020 +0100
@@ -282,7 +282,7 @@
 
 
 /**
- * @brief Strcuture holding a co2 pressure log entry.
+ * @brief Structure holding a co2 pressure log entry.
  */
 typedef struct co2meter_log {
     char			*datetime;		///< Date/time stamp
@@ -310,37 +310,22 @@
 // Make it universal and make it connectable with a beer.
 typedef struct _ispindel_list {
     struct _ispindel_list	*next;
+    char			*uuid;			///< Fixed uuid string.
+    char			*alias;			///< Alias name.
     char			*node;			///< Node name received.
     bool			online;			///< Is considered online.
+    char			*mode;			///< Working mode OFF or ON.
     uint32_t			alarm;			///< Alarm flags.
     char			*beercode;              ///< Beer unique code
     char                        *beername;              ///< Beer name being measured
     char                        *beeruuid;              ///< Beer uuid being measured
-    float			tilt;			///< Tilt angle in degrees
+    float			angle;			///< Tilt angle in degrees
     float			temperature;		///< Temperature in C
     float			battery;		///< Battery voltage
     float			gravity;		///< Gravity in plato?
     int				interval;		///< Measure interval
-    int8_t			rssi;			///< WiFi RSSI
 } sys_ispindel_list;
 
 
 
-/**
- * @brief Standalone temperature loggers. (Freezers, refrigerators, chambers).
- */
-typedef struct _thb_list {
-    struct _thb_list		*next;
-    char			*uuit;			///< Fixed uuid string
-    char			*name;			///< Name or description
-    char			*beercode;		///< Beer code if needed.
-    float			temperature;		///< Temperature in Celcius
-    float			humidity;		///< Humidity in %
-    float			barometer;		///< Air pressure.
-    float			gps_latitude;		///< GPS latitude
-    float			gps_longitude;		///< GPS longitide
-    float			gps_altitude;		///< GPS altitude
-} thb_list;
-
-
 #endif
--- a/bmsd/ispindels.c	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/ispindels.c	Sun Jan 05 11:42:02 2020 +0100
@@ -3,7 +3,7 @@
  * @brief Handle ispindels data
  * @author Michiel Broek <mbroek at mbse dot eu>
  *
- * Copyright (C) 2019
+ * Copyright (C) 2019-2020
  *
  * This file is part of the bms (Brewery Management System)
  *
@@ -40,18 +40,18 @@
 
 
 
-void ispindel_set(char *node, char *key, char *payload)
+void ispindel_set(char *node, char *payload)
 {
     sys_ispindel_list	*ispindel, *tmpp;
-    bool		new_ispindel = true, do_update = false;
-    char		*t, *p, *datetime, buf[65], *line, *logfile;
-    float		temperature = 20;
-    uint8_t		temp_units = 'C';
+    struct json_object  *jobj, *metric, *val;
+    bool		new_ispindel = true;
+    char		*datetime, buf[65], *line, *logfile;
     struct tm           *mytime;
     time_t              timestamp;
     FILE		*fp;
 
-    fprintf(stdout, "ispindel_set: %s %s\n", node, payload);
+    if (debug)
+    	printf("ispindel_set: %s %s\n", node, payload);
 
     /*
      * Search ispindel record in the memory array and use it if found.
@@ -66,7 +66,8 @@
 	}
     }
 
-    printf("new_ispindel %s\n", new_ispindel ? "true":"false");
+    if (debug)
+    	printf("new_ispindel %s\n", new_ispindel ? "true":"false");
 
     /*
      * Allocate new ispindel if not yet known.
@@ -75,64 +76,53 @@
 	ispindel = (sys_ispindel_list *)malloc(sizeof(sys_ispindel_list));
 	memset(ispindel, 0, sizeof(sys_ispindel_list));
 	ispindel->node = xstrcpy(node);
+	ispindel->mode = xstrcpy((char *)"OFF");
     }
 
     if (! ispindel->online) {
     	ispindel->online = true;
-    	syslog(LOG_NOTICE, "Online ispindel %s", node);
+    	syslog(LOG_NOTICE, "Online ispindel %s mode %s", node, ispindel->mode);
     }
 
     /*
-     * Process the simple iSpindel MQTT payload.
+     * Process the JSON formatted payload.
+     * Update only the fields that are found in the payload.
      */
-    if (strcmp(key, "tilt") == 0) {
-	ispindel->tilt = atof(payload);
-    } else if (strcmp(key, "temperature") == 0) {
-	temperature = atof(payload);
-    } else if (strcmp(key, "temp_units") == 0) {
-	temp_units = payload[0];
-    } else if (strcmp(key, "battery") == 0) {
-	ispindel->battery = atof(payload);
-    } else if (strcmp(key, "gravity") == 0) {
-	ispindel->gravity = atof(payload);
-    } else if (strcmp(key, "interval") == 0) {
-	ispindel->interval = atoi(payload);
-    } else if (strcmp(key, "RSSI") == 0) {
-	ispindel->rssi = atoi(payload);
-	do_update = true;
-	if (temp_units == 'C') {
-	    ispindel->temperature = temperature;
-	} else if (temp_units == 'F') {
-	    ispindel->temperature = temperature / 1.8 - 32;
-	} else if (temp_units == 'K') {
-	    ispindel->temperature = temperature - 273.15;
-	} else {
-	    ispindel->temperature = temperature;
-	}
-    } else {
-	syslog(LOG_NOTICE, "Unknown keyword `%s' from `%s'", key, node);
+    jobj = json_tokener_parse(payload);
+
+    if (json_object_object_get_ex(jobj, "unit", &metric)) {
+	if (json_object_object_get_ex(metric, "uuid", &val)) {
+            if (ispindel->uuid)
+                free(ispindel->uuid);
+            ispindel->uuid = xstrcpy((char *)json_object_get_string(val));
+        }
+	if (json_object_object_get_ex(metric, "alias", &val)) {
+            if (ispindel->alias)
+                free(ispindel->alias);
+            ispindel->alias = xstrcpy((char *)json_object_get_string(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)) {
+            ispindel->interval = json_object_get_int(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)) {
+            ispindel->temperature = json_object_get_double(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->battery < LOWBATT)
-	ispindel->alarm |= ALARM_FLAG_BATTERY;
-    else
-	ispindel->alarm &= ~ALARM_FLAG_BATTERY;
-
     ispindel_dump(ispindel);
 
-    if (new_ispindel || do_update) {
-    	t = xstrcpy((char *)"mbv1.0/ispindels/NBIRTH/");
-    	t = xstrcat(t, node);
-
-    	p = xstrcpy((char *)"{\"metric\":{\"properties\":{\"hardwaremake\":\"MBSE\",\"hardwaremodel\":\"Wemos D1 mini\"},\"net\":{\"rssi\":");
-    	sprintf(buf, "%d", ispindel->rssi);
-	p = xstrcat(p, buf);
-    	p = xstrcat(p, (char *)"}}}");
-	node_birth_data(t, p);
-    	free(t);
-    	free(p);
-    }
-
     if (new_ispindel) {
     	if (ispindels == NULL) {
 	    ispindels = ispindel;
@@ -145,14 +135,15 @@
 	    }
 	}
 	ispindel_mysql_insert(ispindel);
-    } else if (do_update) {
+    } else {
 	ispindel_mysql_update(ispindel);
     }
 
     /*
      * The data is complete, see if we can write a log entry.
      */
-    if (do_update && ispindel->beercode && strlen(ispindel->beercode) && ispindel->beername && strlen(ispindel->beername)) {
+    if (ispindel->beercode && strlen(ispindel->beercode) && ispindel->beername && strlen(ispindel->beername) &&
+	(strcmp(ispindel->mode, (char *)"ON") == 0)) {
 	datetime = malloc(72);
 	mytime = localtime(&timestamp);
     	snprintf(datetime, 72, "%04d-%02d-%02d %02d:%02d:%02d",
@@ -160,23 +151,22 @@
 
 	line = xstrcpy(datetime);
     	line = xstrcat(line, (char *)",");
-    	snprintf(buf, 64, "%.3f", ispindel->tilt);
-    	line = xstrcat(line, buf);
-    	line = xstrcat(line, (char *)",");
-	snprintf(buf, 64, "%.3f", ispindel->temperature);
+	snprintf(buf, 64, "%.4f", ispindel->temperature);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
-	snprintf(buf, 64, "%.3f", ispindel->battery);
+	snprintf(buf, 64, "%.5f", ispindel->gravity);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
-	snprintf(buf, 64, "%.3f", ispindel->gravity);
+        snprintf(buf, 64, "%.5f", ispindel->battery);
+        line = xstrcat(line, buf);
+        line = xstrcat(line, (char *)",");
+        snprintf(buf, 64, "%.5f", ispindel->angle);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
 	snprintf(buf, 64, "%d", ispindel->interval);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
-	snprintf(buf, 64, "%d", ispindel->rssi);
-        line = xstrcat(line, buf);
+	line = xstrcat(line, ispindel->uuid);
 
 	/*
 	 * Build logfile name
@@ -210,20 +200,18 @@
 /*
  * Process iSpindel MQTT message.
  */
-void ispindel_mqtt(char *topic, char *payload)
+void ispindel_birth_data(char *topic, char *payload)
 {
-    char		*namespace, *node, *keyword;
+    char		*message_type, *edge_node;
 
-    namespace = strtok(topic, "/"); // must be ispindel
-    node = strtok(NULL, "/");
-    keyword = strtok(NULL, "/\0");
+    strtok(topic, "/"); // ignore namespace
+    strtok(NULL, "/");
+    message_type = strtok(NULL, "/");
+    edge_node = strtok(NULL, "/\0");
 
-    if (strcmp(namespace, "ispindels")) {
-	syslog(LOG_NOTICE, "ispindel_mqtt(%s, %s) error", topic, payload);
-	return;
+    if (strcmp("DBIRTH", message_type) == 0) {
+	ispindel_set(edge_node, payload);
     }
-
-    ispindel_set(node, keyword, payload);
 }
 
 
@@ -231,15 +219,16 @@
 void ispindel_dump(sys_ispindel_list *ispindel)
 {
     if (debug) {
-    	printf("node        %s\n", ispindel->node);
+    	printf("node/alias  %s / %s\n", ispindel->node, ispindel->alias);
+	printf("uuid        %s\n", ispindel->uuid);
 	printf("online      %s\n", ispindel->online ? "yes":"no");
+	printf("mode        %s\n", ispindel->mode);
 	printf("product     %s / %s\n", ispindel->beercode, ispindel->beername);
-        printf("tilt        %.3f\n", ispindel->tilt);
-	printf("temperature %.3f\n", ispindel->temperature);
-	printf("battery     %.3f\n", ispindel->battery);
-	printf("gravity     %.3f\n", ispindel->gravity);
+        printf("tilt        %.5f\n", ispindel->angle);
+	printf("temperature %.5f\n", ispindel->temperature);
+	printf("battery     %.5f\n", ispindel->battery);
+	printf("gravity     %.5f\n", ispindel->gravity);
 	printf("interval    %d\n", ispindel->interval);
-	printf("rssi        %d\n", ispindel->rssi);
     }
 }
 
--- a/bmsd/ispindels.h	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/ispindels.h	Sun Jan 05 11:42:02 2020 +0100
@@ -13,11 +13,10 @@
  *        iSpindel, else the last seen time is updated. Then the last
  *        actual state is recorded. A log line is written when a beer
  *        is assigned.
- * @param topic The MQTT topic string, contains the ispindel name and
- *        keyword for the data.
+ * @param topic The MQTT topic string, contains the ispindel type and name
  * @param payload The value for the selected keyword.
  */
-void ispindel_mqtt(char *topic, char *payload);
+void ispindel_birth_data(char *topic, char *payload);
 
 
 #endif
--- a/bmsd/mqtt.c	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/mqtt.c	Sun Jan 05 11:42:02 2020 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2017-2019
+ * Copyright (C) 2017-2020
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -103,7 +103,7 @@
 	topic = xstrcpy((char *)"mbv1.0/co2meters/#");	// Subscribe to co2meter messages.
 	mosquitto_subscribe(mosq, NULL, topic, 0);
 	free(topic);
-	topic = xstrcpy((char *)"ispindel/#");  // Subscribe to ispindel messages.
+	topic = xstrcpy((char *)"mbv1.0/ispindels/#");  // Subscribe to ispindel messages.
         mosquitto_subscribe(mosq, NULL, topic, 0);
         free(topic);
 	topic = NULL;
@@ -183,8 +183,9 @@
             co2meter_log(message->topic, (char *)message->payload);
             return;
         }
-	if (strstr(message->topic, (char *)"ispindel")) {
-	    ispindel_mqtt(message->topic, (char *)message->payload);
+	if (strstr(message->topic, (char *)"ispindels") && strstr(message->topic, (char *)"DBIRTH")) {
+	    ispindel_birth_data(message->topic, (char *)message->payload);
+	    return;
 	}
 	syslog(LOG_NOTICE, "MQTT: message callback %s :: %d", message->topic, message->payloadlen);
     } else {
--- a/bmsd/mysql.c	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/mysql.c	Sun Jan 05 11:42:02 2020 +0100
@@ -3,7 +3,7 @@
  * @brief MySQL/MariaDB access.
  * @author Michiel Broek <mbroek at mbse dot eu>
  *
- * Copyright (C) 2018-2019
+ * Copyright (C) 2018-2020
  *
  * This file is part of the bms (Brewery Management System)
  *
@@ -286,18 +286,20 @@
                 ispindel = (sys_ispindel_list *)malloc(sizeof(sys_ispindel_list));
                 memset(ispindel, 0, sizeof(sys_ispindel_list));
                 ispindel->next                = NULL;
-		ispindel->node                = xstrcpy(row[1]);
-		ispindel->online              = atoi(row[2]);
-		ispindel->alarm               = atoi(row[3]);
-		ispindel->beercode            = xstrcpy(row[4]);
-                ispindel->beername            = xstrcpy(row[5]);
-                ispindel->beeruuid            = xstrcpy(row[6]);
-		ispindel->tilt                = atof(row[7]);
-		ispindel->temperature         = atof(row[8]);
-                ispindel->battery             = atof(row[9]);
-		ispindel->gravity             = atof(row[10]);
-		ispindel->interval            = atoi(row[11]);
-		ispindel->rssi                = atoi(row[12]);
+		ispindel->uuid		      = xstrcpy(row[1]);
+		ispindel->alias		      = xstrcpy(row[2]);
+		ispindel->node                = xstrcpy(row[3]);
+		ispindel->online              = atoi(row[4]);
+		ispindel->alarm               = atoi(row[5]);
+		ispindel->beercode            = xstrcpy(row[6]);
+                ispindel->beername            = xstrcpy(row[7]);
+                ispindel->beeruuid            = xstrcpy(row[8]);
+		ispindel->angle               = atof(row[9]);
+		ispindel->temperature         = atof(row[10]);
+                ispindel->battery             = atof(row[11]);
+		ispindel->gravity             = atof(row[12]);
+		ispindel->interval            = atoi(row[13]);
+		ispindel->mode		      = xstrcpy(row[14]);
 
                 if (ispindels == NULL) {
                     ispindels = ispindel;
@@ -507,11 +509,11 @@
 	"INSERT INTO  mon_nodes SET uuid='%s', node='%s', online='%d', group_id='%s', " \
         "hardwaremake='%s', hardwaremodel='%s', os='%s', os_version='%s', firmware='%s', firstseen='%s', lastseen='%s', " \
 	"temperature='%.3f', humidity='%.3f', barometer='%.3f', gps_latitude='%.8f', gps_longitude='%.8f', gps_altitude='%.8f', " \
-	"net_address='%s', net_ifname='%s', net_rssi='%d'",
+	"net_address='%s', net_ifname='%s', net_rssi='%d', up_interval='%d'",
 	node->uuid, node->node, node->online ?1:0, node->group_id, 
 	node->hardwaremake, node->hardwaremodel, node->os, node->os_version, node->firmware, first, last,
 	node->temperature, node->humidity, node->barometer, node->gps_latitude, node->gps_longitude, node->gps_altitude,
-	node->net_address, node->net_ifname, node->net_rssi);
+	node->net_address, node->net_ifname, node->net_rssi, node->interval);
 
     if (bms_mysql_query(query) == 0) {
 	syslog(LOG_NOTICE,  "MySQL: insert new node %s", node->node);
@@ -534,10 +536,10 @@
     snprintf(query, 1023,
 	"UPDATE mon_nodes SET online='%d', hardwaremake='%s', hardwaremodel='%s', os='%s', os_version='%s', firmware='%s', lastseen='%s', " \
 	"temperature='%.3f', humidity='%.3f', barometer='%.3f', gps_latitude='%.8f', gps_longitude='%.8f', gps_altitude='%.8f', " \
-	"net_address='%s', net_ifname='%s', net_rssi='%d' WHERE uuid='%s'",
+	"net_address='%s', net_ifname='%s', net_rssi='%d', up_interval='%d' WHERE uuid='%s'",
 	node->online ? 1:0, node->hardwaremake, node->hardwaremodel, node->os, node->os_version, node->firmware, last,
 	node->temperature, node->humidity, node->barometer, node->gps_latitude, node->gps_longitude, node->gps_altitude, 
-	node->net_address, node->net_ifname, node->net_rssi, node->uuid);
+	node->net_address, node->net_ifname, node->net_rssi, node->interval, node->uuid);
 
     bms_mysql_query(query);
     free(query);
@@ -720,10 +722,10 @@
     char        *query = malloc(2560);
 
     snprintf(query, 2559,
-        "INSERT INTO mon_ispindels SET node='%s', online='%d', alarm='%d', " \
-        "tilt='%.6f', temperature='%.4f', battery='%.4f', gravity='%.6f', interval='%d', rssi='%d'",
-        ispindel->node, ispindel->online ? 1:0, ispindel->alarm,
-        ispindel->tilt, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval, ispindel->rssi);
+        "INSERT INTO mon_ispindels SET uuid='%s', alias='%s', node='%s', online='%d', mode='%s', alarm='%d', " \
+        "angle='%.6f', temperature='%.4f', battery='%.4f', gravity='%.6f', up_interval='%d'",
+        ispindel->uuid, ispindel->alias, ispindel->node, ispindel->online ? 1:0, ispindel->mode, ispindel->alarm,
+        ispindel->angle, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval);
 
     if (bms_mysql_query(query) == 0) {
         syslog(LOG_NOTICE,  "MySQL: insert new ispindel %s", ispindel->node);
@@ -738,10 +740,10 @@
     char        *query = malloc(2560);
 
     snprintf(query, 2559,
-        "UPDATE mon_ispindels SET online='%d', alarm='%d', " \
-	"tilt='%.3f', temperature='%.3f', battery='%.3f', gravity='%.3f', interval='%d', rssi='%d' WHERE node='%s'",
-        ispindel->online ? 1:0, ispindel->alarm,
-	ispindel->tilt, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval, ispindel->rssi, ispindel->node);
+        "UPDATE mon_ispindels SET online='%d', mode='%s', alarm='%d', " \
+	"angle='%.3f', temperature='%.3f', battery='%.3f', gravity='%.3f', up_interval='%d' WHERE uuid='%s'",
+        ispindel->online ? 1:0, ispindel->mode, ispindel->alarm,
+	ispindel->angle, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval, ispindel->uuid);
 
     bms_mysql_query(query);
     free(query);
@@ -749,11 +751,11 @@
 
 
 
-void ispindel_mysql_death(char *node)
+void ispindel_mysql_death(char *uuid)
 {
     char        *query = malloc(512);
 
-    snprintf(query, 511, "UPDATE mon_ispindels SET online='0' WHERE node='%s'", node);
+    snprintf(query, 511, "UPDATE mon_ispindels SET online='0' WHERE uuid='%s'", uuid);
     bms_mysql_query(query);
     free(query);
 }
--- a/bmsd/nodes.c	Fri Jan 03 15:21:22 2020 +0100
+++ b/bmsd/nodes.c	Sun Jan 05 11:42:02 2020 +0100
@@ -3,7 +3,7 @@
  * @brief Handle nodes status
  * @author Michiel Broek <mbroek at mbse dot eu>
  *
- * Copyright (C) 2018-2019
+ * Copyright (C) 2018-2020
  *
  * This file is part of the bms (Brewery Management System)
  *
@@ -82,6 +82,7 @@
     	node->gps_latitude = node->gps_longitude = node->gps_altitude = 0.0;
 	node->net_address = node->net_ifname = NULL;
 	node->net_rssi = 0;
+	node->interval = 300;
     }
 
     /*
@@ -111,6 +112,9 @@
 		free(node->uuid);
 	    node->uuid = xstrcpy((char *)json_object_get_string(val));
 	}
+	if (json_object_object_get_ex(metric, "interval", &val)) {
+	    node->interval = json_object_get_int(val);
+	}
 	if (json_object_object_get_ex(metric, "properties", &metric2)) {
 	    if (json_object_object_get_ex(metric2, "hardwaremake", &val)) {
 		if (node->hardwaremake)
@@ -214,6 +218,7 @@
     	printf("GPS       %.5f  %.5f  %.5f\n", node->gps_latitude, node->gps_longitude, node->gps_altitude);
 	printf("net       %s:%s\n", node->net_ifname, node->net_address);
 	printf("rssi      %d\n", node->net_rssi);
+	printf("interval  %d\n", node->interval);
     }
 }
 
@@ -251,8 +256,8 @@
     time_t		now = time(NULL);
 
     for (tmpn = nodes; tmpn; tmpn = tmpn->next) {
-	if (debug)
-	    printf("%-20s online %s  %ld  %d\n", tmpn->node, tmpn->online ? "yes":"no ", tmpn->lastseen, tmpn->interval);
+//	if (debug)
+//	    printf("%-20s online %s  %ld  %d\n", tmpn->node, tmpn->online ? "yes":"no ", tmpn->lastseen, tmpn->interval);
 	if (tmpn->online && ((now - tmpn->lastseen) > (tmpn->interval * 2 + 5))) { // 2 times interval + 5 seconds
 	    syslog(LOG_NOTICE, "Timeout node `%s/%s' after %ld seconds", tmpn->group_id, tmpn->node, (now - tmpn->lastseen));
 	    tmpn->online = false;
--- a/www/Makefile	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/Makefile	Sun Jan 05 11:42:02 2020 +0100
@@ -62,6 +62,7 @@
 		${INSTALL} -d -g 314 -o 314 ${WWWDIR}/log/brews
 		${INSTALL} -d -g 314 -o 314 ${WWWDIR}/log/fermentation
 		${INSTALL} -d -g 314 -o 314 ${WWWDIR}/log/co2pressure
+		${INSTALL} -d -g 314 -o 314 ${WWWDIR}/log/ispindel
 		${INSTALL} -g 314 -o 314 -m 0644 ${SRC} ${WWWDIR}/
 		${INSTALL} -g 314 -o 314 -m 0644 version.php ${WWWDIR}/
 		${INSTALL} -g 314 -o 314 -m 0644 css/* ${WWWDIR}/css/
--- a/www/cmd_ispindel.php	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/cmd_ispindel.php	Sun Jan 05 11:42:02 2020 +0100
@@ -7,18 +7,23 @@
         die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
 }
 mysqli_set_charset($connect, "utf8" );
+$sql = "";
 
-$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 .= "' WHERE node='" . $_POST['node'] . "';";
+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 .= "' WHERE uuid='" . $_POST['uuid'] . "';";
+} else if (isset($_POST['mode'])) {
+	$sql  = "UPDATE `mon_ispindels` SET mode='" .$_POST['mode'] . "' WHERE uuid='" . $_POST['uuid'] . "';";
+}
 
 $result = mysqli_query($connect, $sql);
 if (! $result) {
 	syslog(LOG_NOTICE, "cmd_ispindel: result: ".mysqli_error($connect));
 } else {
-	syslog(LOG_NOTICE, "cmd_ispindel: updated record ".$_POST['node']);
+	syslog(LOG_NOTICE, "cmd_ispindel: updated record ".$_POST['uuid']);
 }
 echo $result;
 ?>
--- a/www/getispindel.php	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/getispindel.php	Sun Jan 05 11:42:02 2020 +0100
@@ -9,7 +9,7 @@
 
 
 $mysqli = new mysqli(DBASE_HOST,DBASE_USER,DBASE_PASS,DBASE_NAME);
-$query = "SELECT * FROM mon_ispindels WHERE node=".$uuid."";
+$query = "SELECT * FROM mon_ispindels WHERE uuid=".$uuid."";
 $result = $mysqli->query($query);
 $resultArray = $result->fetch_array(MYSQLI_ASSOC);
 header("Content-type: application/json");
--- a/www/includes/global.inc.php	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/includes/global.inc.php	Sun Jan 05 11:42:02 2020 +0100
@@ -248,13 +248,13 @@
        <li><img style='float: left; margin-right: 5px;' src='images/fermenter.png' />iSpindels
         <ul style='width: 250px;'>
 <?php
-$result = mysqli_query($connect, "SELECT node,online FROM mon_ispindels ORDER BY node");
+$result = mysqli_query($connect, "SELECT uuid,node,alias,online FROM mon_ispindels ORDER BY node,alias");
 while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
     if ($row['online'] == 1)
         $img = "network-idle.png";
     else
         $img = "network-error.png";
-    echo '         <li><img style="float: left; margin-right: 5px;" src="images/'.$img.'" /><a href="mon_ispindel.php?uuid='.$row['node'].'">'.$row['node'].'</a></li>'.PHP_EOL;
+    echo '         <li><img style="float: left; margin-right: 5px;" src="images/'.$img.'" /><a href="mon_ispindel.php?uuid='.$row['uuid'].'">'.$row['alias'].'</a></li>'.PHP_EOL;
 }
 mysqli_free_result($result);
 ?>
--- a/www/js/mon_ispindel.js	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/js/mon_ispindel.js	Sun Jan 05 11:42:02 2020 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2019
+ * Copyright (C) 2019-2020
  *
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -26,6 +26,7 @@
  var record = {},
  blank = {},
  newProduct = false,
+ newMode = false,
  schedule = 0,
 
  productSource = {
@@ -81,23 +82,25 @@
   colorScheme: 'scheme05',
   showRanges: false
  },
- url = 'getispindel.php?node="' + my_uuid + '"',
+ url = 'getispindel.php?uuid="' + my_uuid + '"',
  source = {
   datatype: 'json',
   datafields: [
    { name: 'record', type: 'int' },
+   { name: 'uuid', type: 'string' },
+   { name: 'alias', type: 'string' },
    { name: 'node', type: 'string' },
    { name: 'online', type: 'int' },
    { name: 'beercode', type: 'string' },
    { name: 'beername', type: 'string' },
    { name: 'beeruuid', type: 'string' },
    { name: 'alarm', type: 'int' },
-   { name: 'tilt', type: 'float' },
+   { name: 'angle', type: 'float' },
    { name: 'temperature', type: 'float' },
    { name: 'battery', type: 'float' },
    { name: 'gravity', type: 'float' },
-   { name: 'interval', type: 'int' },
-   { name: 'rssi', type: 'int' }
+   { name: 'up_interval', type: 'int' },
+   { name: 'mode', type: 'string' }
   ],
   id: 'record',
   url: url
@@ -106,14 +109,16 @@
   loadComplete: function(records) {
    record = dataAdapter.records[0];
    var oline = (record.online) ? 'On-line' : 'Off-line';
-   $('#info_system').html(record.node);
+   $('#info_uuid').html(record.uuid);
+   $('#info_system').html(record.node + '/' + record.alias);
    $('#info_online').html(oline);
    $('#info_beer').html(record.beercode + ' - ' + record.beername);
-//   blank['name'] = record.alias;
-//   blank['code'] = record.alias.toUpperCase();
-//   blank['uuid'] = record.uuid;
+   $('#info_mode').jqxDropDownList('selectItem', record.mode);
+   blank['name'] = record.alias;
+   blank['code'] = record.alias.toUpperCase();
+   blank['uuid'] = record.uuid;
 
-   if (record.online) {
+   if (record.online && (record.mode != 'OFF')) {
     $('#ispindel_powerled').html('<div class="LEDblue_on"></div>Power');
     $('#select_beer').jqxDropDownList({ disabled: true });
     $('#select_beer').jqxDropDownList('clearSelection');
@@ -133,8 +138,7 @@
    $('#gaugeContainer_temperature').jqxGauge({ value: record.temperature });
 
    $('#info_battery').val(record.battery);
-   $('#info_rssi').val(record.rssi);
-   $('#info_tilt').val(record.tilt);
+   $('#info_tilt').val(record.angle);
 
    gravity = plato_to_sg(record.gravity) * 1000;
    $('#gaugeContainer_gravity').jqxLinearGauge({ value: gravity });
@@ -157,17 +161,19 @@
  });
 
  $('#info_battery').jqxNumberInput(Show3dec);
- $('#info_rssi').jqxNumberInput(Show0dec);
  $('#info_tilt').jqxNumberInput(Show3dec);
 
  $('#gaugeContainer_temperature').jqxGauge(gaugeoptionst);
  $('#gaugeContainer_temperature').jqxGauge({ caption: { value: 'Temp: 00.000' }});
  $('#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 = 'node=' + record.node + '&beeruuid=' + uuid + '&beercode=' + code + '&beername=' + name;
+  var data = 'uuid=' + record.uuid + '&beeruuid=' + uuid + '&beercode=' + code + '&beername=' + name;
   $.ajax({
    url: 'cmd_ispindel.php',
    data: data,
@@ -177,10 +183,28 @@
   });
  }
 
+ 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.
  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;
@@ -209,6 +233,13 @@
    newProduct = true;
   }
  });
+ $('#info_mode').on('change', function(event) {
+  var args = event.args;
+  if (args) {
+   record.mode = args.item.value;
+  }
+  newMode = true;
+ });
 
  // The chart button.
  $('#VLog').jqxButton({ template: 'primary', width: '150px', theme: theme });
--- a/www/js/mon_node.js	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/js/mon_node.js	Sun Jan 05 11:42:02 2020 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2019
+ * Copyright (C) 2019-2020
  *
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -47,7 +47,8 @@
    { name: 'gps_altitude', type: 'float' },
    { name: 'net_address', type: 'string' },
    { name: 'net_ifname', type: 'string' },
-   { name: 'net_rssi', type: 'int' }
+   { name: 'net_rssi', type: 'int' },
+   { name: 'up_interval', type: 'int' }
   ],
   id: 'record',
   url: url
@@ -70,7 +71,9 @@
    html += '<tr><td>OS</td><td>' + record.os + ' versie: ' + record.os_version + '</td></tr>';
    html += '<tr><td>Firmware</td><td>' + record.firmware + '</td></tr>';
    if (record.online) {
-    html += '<tr><td>Temperatuur</td><td>' + record.temperature.toFixed(1) + '&deg;C</td></tr>';
+    if (record.temperature > 0) {
+     html += '<tr><td>Temperatuur</td><td>' + record.temperature.toFixed(1) + '&deg;C</td></tr>';
+    }
     if (record.humidity > 0) {
      html += '<tr><td>Vochtigheid</td><td>' + record.humidity.toFixed(1) + '%</td></tr>';
     }
@@ -81,6 +84,10 @@
      html += '<tr><td>GPS</td><td>' + record.gps_latitude + ' ' + record.gps_longitude + ' ' + record.gps_altitude + '</td></tr>';
     }
     html += '<tr><td>Netwerk</td><td>' + record.net_ifname + ' ' + record.net_address + '</td></tr>';
+    if (record.net_rssi < 0) {
+     html += '<tr><td>WiFi signaal</td><td>' + record.net_rssi + '</td></tr>';
+    }
+    html += '<tr><td>Update interval</td><td>' + record.up_interval + ' sec.</td></tr>';
    }
    html += '</<table>';
    html += '</div>';
--- a/www/mon_ispindel.php	Fri Jan 03 15:21:22 2020 +0100
+++ b/www/mon_ispindel.php	Sun Jan 05 11:42:02 2020 +0100
@@ -13,7 +13,10 @@
 	<col width="40%">
         <col width="40%">
         <tr><th colspan=3>iSpindel overzicht</th></tr>
-        <tr><td colspan=3>&nbsp;</td></tr>
+        <tr style="height: 25px;">
+         <td>Uuid</td>
+         <td colspan="2"><div id="info_uuid"></div></td>
+        </tr>
 	<tr style="height: 25px;">
          <td>Systeem</td>
 	 <td><div id="info_system"></div></td>
@@ -24,16 +27,16 @@
          <td><div id="info_beer"></div></td>
          <td><div id="select_beer"></div></td>
         </tr>
+        <tr style="height: 25px;">
+         <td>Werking</td>
+         <td colspan="2"><div id="info_mode"></div></td>
+        </tr>
 	<tr style="height: 25px;">
-         <td>Battery</td>
+         <td>Batterij volt</td>
          <td colspan="2"><div id="info_battery"></div></td>
         </tr>
         <tr style="height: 25px;">
-         <td>WiFi signaal</td>
-         <td colspan="2"><div id="info_rssi"></div></td>
-        </tr>
-        <tr style="height: 25px;">
-         <td>Tilt hoek</td>
+         <td>Tilt hoek &deg;</td>
          <td colspan="2"><div id="info_tilt"></div></td>
         </tr>
        </table>

mercurial