Version 0.3.44. Moved iSpindel Plato calculation from the php script to bmsd. This uses calibration data in the mon_ispindels table. Setup of this data will be done by the bmsapp applications. Default settings are stored in MySQL. From now on you don't need to store calibration data in the iSpindel.

Thu, 12 Oct 2023 14:19:46 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 12 Oct 2023 14:19:46 +0200
changeset 849
16079aef4c4c
parent 848
542bdc7f6522
child 850
26cc7ea0f790

Version 0.3.44. Moved iSpindel Plato calculation from the php script to bmsd. This uses calibration data in the mon_ispindels table. Setup of this data will be done by the bmsapp applications. Default settings are stored in MySQL. From now on you don't need to store calibration data in the iSpindel.

bmsd/bms.h file | annotate | diff | comparison | revisions
bmsd/ispindels.c file | annotate | diff | comparison | revisions
bmsd/mysql.c file | annotate | diff | comparison | revisions
bmsd/mysql.h file | annotate | diff | comparison | revisions
config.status file | annotate | diff | comparison | revisions
configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
www/ispindel/index.php file | annotate | diff | comparison | revisions
--- a/bmsd/bms.h	Wed Aug 23 10:30:09 2023 +0200
+++ b/bmsd/bms.h	Thu Oct 12 14:19:46 2023 +0200
@@ -332,6 +332,8 @@
     float			og_gravity;		///< OG gravity in Plato detected
     float			yeast_lo;		///< Yeast low temperature limit
     float			yeast_hi;		///< Yeast high temperature limit
+    char			*calibrate;		///< Calibration data
+    time_t			lastseen;		///< iSpindel last seen
 } sys_ispindel_list;
 
 
--- a/bmsd/ispindels.c	Wed Aug 23 10:30:09 2023 +0200
+++ b/bmsd/ispindels.c	Thu Oct 12 14:19:46 2023 +0200
@@ -40,6 +40,14 @@
 extern MYSQL_ROW	row;
 
 
+
+double plato_to_sg(double plato)
+{
+    return 1.00001 + (0.0038661 * plato) + (1.3488e-5 * pow(plato, 2)) + (4.3074e-8 * pow(plato, 3));
+}
+
+
+
 void ispindel_ws_send(sys_ispindel_list *ispindel)
 {
     char	*msg = NULL, buf[65];
@@ -225,7 +233,7 @@
     time_t              timestamp;
     FILE		*fp;
 
-    // syslog(LOG_NOTICE, "ispindel_set: %s %s", node, payload);
+    syslog(LOG_NOTICE, "ispindel_set: %s %s", node, payload);
 
     /*
      * Search ispindel record in the memory array and use it if found.
@@ -265,6 +273,7 @@
     jobj = json_tokener_parse(payload);
 
     if (json_object_object_get_ex(jobj, "unit", &metric)) {
+	ispindel->lastseen = time(NULL);
 	if (json_object_object_get_ex(metric, "uuid", &val)) {
             if (ispindel->uuid)
                 free(ispindel->uuid);
@@ -285,16 +294,15 @@
             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)) {
+	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;
-        }
     }
 
-//    ispindel_dump(ispindel);
+    //ispindel_dump(ispindel);
 
-
+    /*
+     * If a new iSpindel, insert record.
+     */
     if (new_ispindel) {
     	if (ispindels == NULL) {
 	    ispindels = ispindel;
@@ -307,9 +315,16 @@
 	    }
 	}
 	ispindel_mysql_insert(ispindel);
-    } else {
-	ispindel_mysql_update(ispindel);
     }
+
+    /*
+     * Calculate Plato using the calibration data.
+     * Then update again and make it available.
+     */
+    ispindel->gravity = ispindel_mysql_plato(ispindel->uuid, ispindel->angle);
+    if (ispindel->gravity > ispindel->og_gravity)
+	ispindel->og_gravity = ispindel->gravity;
+    ispindel_mysql_update(ispindel);
     ispindel_ws_send(ispindel);
 
     /*
@@ -331,8 +346,7 @@
 	snprintf(buf, 64, "%.5f", ispindel->gravity);
         line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
-	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));
+	snprintf(buf, 64, "%.5f", plato_to_sg(ispindel->gravity));
 	line = xstrcat(line, buf);
         line = xstrcat(line, (char *)",");
         snprintf(buf, 64, "%.6f", ispindel->battery);
@@ -349,9 +363,7 @@
 	snprintf(query, 511, "INSERT IGNORE INTO log_ispindel SET code='%s', datetime='%s', " \
 			"temperature='%.4f', plato='%.5f', sg='%.5f', battery='%.6f', " \
 			"angle='%.5f', refresh='%d', uuid='%s'",
-			ispindel->beercode, datetime, ispindel->temperature, ispindel->gravity,
-			1.00001 + (0.0038661 * ispindel->gravity) + (1.3488e-5 * ispindel->gravity * ispindel->gravity) +
-				(4.3074e-8 * ispindel->gravity * ispindel->gravity * ispindel->gravity),
+			ispindel->beercode, datetime, ispindel->temperature, ispindel->gravity, plato_to_sg(ispindel->gravity),
 			ispindel->battery, ispindel->angle, ispindel->interval, ispindel->uuid);
 	//syslog(LOG_NOTICE, "%s", query);
 	bms_mysql_query(query);
@@ -416,8 +428,12 @@
 	printf("temperature %.4f\n", ispindel->temperature);
 	printf("battery     %.6f\n", ispindel->battery);
 	printf("gravity     %.5f\n", ispindel->gravity);
+	printf("last seen   %ld\n", ispindel->lastseen);
 	printf("interval    %d\n", ispindel->interval);
 	printf("og_gravity  %.5f\n", ispindel->og_gravity);
+	printf("yeast_lo    %.1f\n", ispindel->yeast_lo);
+	printf("yeast_hi    %.1f\n", ispindel->yeast_hi);
+	printf("calibrate   %s\n", ispindel->calibrate);
     }
 }
 
--- a/bmsd/mysql.c	Wed Aug 23 10:30:09 2023 +0200
+++ b/bmsd/mysql.c	Thu Oct 12 14:19:46 2023 +0200
@@ -308,6 +308,8 @@
 		ispindel->og_gravity	      = atof(row[15]);
 		ispindel->yeast_lo	      = atof(row[16]);
 		ispindel->yeast_hi	      = atof(row[17]);
+		ispindel->calibrate           = xstrcpy(row[18]);
+		ispindel->lastseen            = datetime_to_time_t(row[19]);
 
                 if (ispindels == NULL) {
                     ispindels = ispindel;
@@ -360,6 +362,8 @@
             free(tmpi->beeruuid);
 	if (tmpi->mode)
 	    free(tmpi->mode);
+	if (tmpi->calibrate)
+	    free(tmpi->calibrate);
         free(tmpi);
     }
 
@@ -710,17 +714,63 @@
 
 
 
+/*
+ * Update the gravity calculated from the calibrate data.
+ */
+double ispindel_mysql_plato(char *uuid, double angle)
+{
+    char		*query = malloc(1024), *cal;
+    struct json_object	*jobj, *metric, *val;
+    double		poly[4], plato = 0;
+
+    snprintf(query, 1023, "SELECT uuid,calibrate FROM mon_ispindels WHERE uuid='%s'", uuid);
+    if (mysql_query(con, query)) {
+	syslog(LOG_NOTICE, "MySQL: %s error %u (%s))", query, mysql_errno(con), mysql_error(con));
+	free(query);
+	return 0.0;
+    }
+
+    res_set = mysql_store_result(con);
+    if (res_set == NULL) {
+	syslog(LOG_NOTICE, "MySQL: mysq_store_result error %u (%s))", mysql_errno(con), mysql_error(con));
+	free(query);
+	return 0.0;
+    }
+    free(query);
+
+    if ((row = mysql_fetch_row(res_set)) != NULL) {
+    	cal = xstrcpy(row[1]);
+	jobj = json_tokener_parse(cal);
+	if (json_object_object_get_ex(jobj, "polyData", &metric)) {
+	    int arraylen = json_object_array_length(metric);
+	    for (int i = 0; i < arraylen; i++) {
+		val = json_object_array_get_idx(metric, i);
+		poly[i] = json_object_get_double(val);
+	    }
+	    plato = (poly[0] * pow(angle, 3)) + (poly[1] * pow(angle, 2)) + (poly[2] * angle) + poly[3];
+	}
+	free(cal);
+    }
+    return plato;
+}
+
+
 void ispindel_mysql_insert(sys_ispindel_list *ispindel)
 {
-    char        *query = malloc(2560);
+    char        *query = malloc(2560), last[73];
+    struct tm   *mytime;
+
+    mytime = localtime(&ispindel->lastseen);
+    snprintf(last, 64, "%04d-%02d-%02d %02d:%02d:%02d",
+        mytime->tm_year + 1900, mytime->tm_mon + 1, mytime->tm_mday, mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
 
     snprintf(query, 2559,
         "INSERT INTO mon_ispindels SET uuid='%s', alias='%s', node='%s', online='%d', mode='%s', alarm='%d', " \
         "angle='%.6f', temperature='%.4f', battery='%.6f', gravity='%.6f', up_interval='%d', og_gravity='0.0', " \
-	"yeast_lo='%.1f', yeast_hi='%.1f'",
+	"yeast_lo='%.1f', yeast_hi='%.1f', lastseen='%s'",
         ispindel->uuid, ispindel->alias, ispindel->node, ispindel->online ? 1:0, ispindel->mode, ispindel->alarm,
         ispindel->angle, ispindel->temperature, ispindel->battery, ispindel->gravity, ispindel->interval,
-	ispindel->yeast_lo, ispindel->yeast_hi);
+	ispindel->yeast_lo, ispindel->yeast_hi, last);
 
     if (bms_mysql_query(query) == 0) {
         syslog(LOG_NOTICE,  "MySQL: insert new ispindel %s", ispindel->node);
@@ -732,15 +782,23 @@
 
 void ispindel_mysql_update(sys_ispindel_list *ispindel)
 {
-    char        *query = malloc(2560);
+    char        *query = malloc(2560), last[73];
+    struct tm   *mytime;
 
+    mytime = localtime(&ispindel->lastseen);
+    snprintf(last, 64, "%04d-%02d-%02d %02d:%02d:%02d",
+        mytime->tm_year + 1900, mytime->tm_mon + 1, mytime->tm_mday, mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
+
+    /*
+     * Do not update the calibrate field with regular updates.
+     */
     snprintf(query, 2559,
         "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'), " \
-        "yeast_lo='%.1f', yeast_hi='%.1f' WHERE uuid='%s'",
+        "yeast_lo='%.1f', yeast_hi='%.1f', lastseen='%s' 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->yeast_lo, ispindel->yeast_hi, ispindel->uuid);
+	ispindel->yeast_lo, ispindel->yeast_hi, last, ispindel->uuid);
     bms_mysql_query(query);
     free(query);
 }
--- a/bmsd/mysql.h	Wed Aug 23 10:30:09 2023 +0200
+++ b/bmsd/mysql.h	Thu Oct 12 14:19:46 2023 +0200
@@ -36,6 +36,7 @@
 void co2meter_mysql_update(sys_co2meter_list *co2meter);
 void co2meter_mysql_death(char *node, char *alias);
 
+double ispindel_mysql_plato(char *uuid, double angle);
 void ispindel_mysql_insert(sys_ispindel_list *ispindel);
 void ispindel_mysql_update(sys_ispindel_list *ispindel);
 void ispindel_mysql_death(char *alias);
--- a/config.status	Wed Aug 23 10:30:09 2023 +0200
+++ b/config.status	Thu Oct 12 14:19:46 2023 +0200
@@ -433,7 +433,7 @@
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
-ac_pwd='/home/mbroek/MyProjects/bms'
+ac_pwd='/mnt/home/mbroek/MyProjects/bms'
 srcdir='.'
 test -n "$AWK" || AWK=awk
 # The default lists apply if the user does not specify any file.
@@ -621,7 +621,7 @@
 S["CC"]="gcc"
 S["CYEARS"]="2016-2023"
 S["COPYRIGHT"]="Copyright (C) 2016-2023 Michiel Broek, All Rights Reserved"
-S["VERSION"]="0.3.43"
+S["VERSION"]="0.3.44"
 S["PACKAGE"]="bms"
 S["SUBDIRS"]="bmsd doc script tools www"
 S["target_alias"]=""
@@ -709,7 +709,7 @@
 D["PACKAGE_STRING"]=" \"\""
 D["PACKAGE_BUGREPORT"]=" \"\""
 D["PACKAGE_URL"]=" \"\""
-D["VERSION"]=" \"0.3.43\""
+D["VERSION"]=" \"0.3.44\""
 D["COPYRIGHT"]=" \"Copyright (C) 2016-2023 Michiel Broek, All Rights Reserved\""
 D["STDC_HEADERS"]=" 1"
 D["HAVE_SYS_TYPES_H"]=" 1"
--- a/configure	Wed Aug 23 10:30:09 2023 +0200
+++ b/configure	Thu Oct 12 14:19:46 2023 +0200
@@ -2031,7 +2031,7 @@
 
 
 PACKAGE="bms"
-VERSION="0.3.43"
+VERSION="0.3.44"
 COPYRIGHT="Copyright (C) 2016-2023 Michiel Broek, All Rights Reserved"
 CYEARS="2016-2023"
 
--- a/configure.ac	Wed Aug 23 10:30:09 2023 +0200
+++ b/configure.ac	Thu Oct 12 14:19:46 2023 +0200
@@ -8,7 +8,7 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="bms"
-VERSION="0.3.43"
+VERSION="0.3.44"
 COPYRIGHT="Copyright (C) 2016-2023 Michiel Broek, All Rights Reserved"
 CYEARS="2016-2023"
 AC_SUBST(PACKAGE)
--- a/www/ispindel/index.php	Wed Aug 23 10:30:09 2023 +0200
+++ b/www/ispindel/index.php	Thu Oct 12 14:19:46 2023 +0200
@@ -17,11 +17,6 @@
                 $tempC = floatval($data['temperature']);
 	}
 
-	/* The rounding in the tilt using less digits results in a 0.25 plato difference. Calculate here again using the calibration data. */
-	$tilt = $data['angle'];
-	$plato = (0.00028548 * $tilt * $tilt * $tilt) + (-0.03492272 * $tilt * $tilt) + (1.617106176 * $tilt) + -21.412976092;
-	syslog(LOG_NOTICE, "ispindel " . $input . " plato ".$plato);
-
 	$node = 'ispindel-' . sprintf("%06x", floatval($data['ID']));
 
 	$alarm = 0;
@@ -49,7 +44,7 @@
 	$uuid = 'c0ffeeee-cafe-dead-bee0-' . sprintf("%06x", 0xffffff - floatval($data['ID'])) . sprintf("%06x", floatval($data['ID']));
 	$topic = 'mbv1.0/ispindels/DBIRTH/' . $node;
 	$payload  = '{"unit":{"uuid":"' . $uuid .'","alias":"' . $data['name'] . '","alarm":' . $alarm . ',"interval":' . $interval;
-	$payload .= ',"angle":' . $data['angle'] . ',"temperature":' . $tempC . ',"battery":' . $data['battery'] . ',"gravity":' . $plato . '}}';
+	$payload .= ',"angle":' . $data['angle'] . ',"temperature":' . $tempC . ',"battery":' . $data['battery'] . ',"gravity":' . $data['gravity'] . '}}';
 	$pub = $publisher . $topic . ' -m \'' .$payload . '\'';
 	exec($pub);
 }

mercurial