bmsd/ispindels.c

branch
stable
changeset 665
4d01937ae7af
parent 654
0aef416dbceb
child 675
a27af02ab16a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bmsd/ispindels.c	Fri May 01 16:37:31 2020 +0200
@@ -0,0 +1,241 @@
+/**
+ * @file ispindels.c
+ * @brief Handle ispindels data
+ * @author Michiel Broek <mbroek at mbse dot eu>
+ *
+ * Copyright (C) 2019-2020
+ *
+ * This file is part of the bms (Brewery Management System)
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * bms is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ThermFerm; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+
+#include "bms.h"
+#include "xutil.h"
+#include "ispindels.h"
+#include "mysql.h"
+#include "nodes.h"
+
+
+sys_ispindel_list	*ispindels = NULL;
+
+extern int		debug;
+extern sys_config       Config;
+extern MYSQL		*con;
+extern MYSQL_RES	*res_set;
+extern MYSQL_ROW	row;
+
+
+
+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;
+    struct tm           *mytime;
+    time_t              timestamp;
+    FILE		*fp;
+
+//    if (debug)
+//    	printf("ispindel_set: %s %s\n", node, payload);
+
+    /*
+     * 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) {
+		new_ispindel = false;
+		ispindel = tmpp;
+		break;
+	    }
+	}
+    }
+
+//    if (debug)
+//    	printf("new_ispindel %s\n", new_ispindel ? "true":"false");
+
+    /*
+     * Allocate new ispindel if not yet known.
+     */
+    if (new_ispindel) {
+	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 mode %s", node, ispindel->mode);
+    }
+
+    /*
+     * Process the JSON formatted payload.
+     * Update only the fields that are found in the payload.
+     */
+    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);
+        }
+    }
+
+//    ispindel_dump(ispindel);
+
+    if (new_ispindel) {
+    	if (ispindels == NULL) {
+	    ispindels = ispindel;
+	} else {
+	    for (tmpp = ispindels; tmpp; tmpp = tmpp->next) {
+		if (tmpp->next == NULL) {
+		    tmpp->next = ispindel;
+		    break;
+		}
+	    }
+	}
+	ispindel_mysql_insert(ispindel);
+    } else {
+	ispindel_mysql_update(ispindel);
+    }
+
+    /*
+     * The data is complete, see if we can write a log entry.
+     */
+    if (ispindel->beercode && strlen(ispindel->beercode) && ispindel->beername && strlen(ispindel->beername) &&
+	ispindel->online && (strcmp(ispindel->mode, (char *)"ON") == 0)) {
+	datetime = malloc(72);
+	timestamp = time(NULL);
+	mytime = localtime(&timestamp);
+    	snprintf(datetime, 72, "%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);
+
+	line = xstrcpy(datetime);
+    	line = xstrcat(line, (char *)",");
+	snprintf(buf, 64, "%.4f", ispindel->temperature);
+        line = xstrcat(line, buf);
+        line = xstrcat(line, (char *)",");
+	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);
+        line = xstrcat(line, (char *)",");
+        snprintf(buf, 64, "%.6f", 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 *)",");
+	line = xstrcat(line, ispindel->uuid);
+
+	/*
+	 * Build logfile name
+	 */
+	logfile = xstrcpy(Config.web_root);
+	logfile = xstrcat(logfile, (char *)"/log/ispindel/");
+	logfile = xstrcat(logfile, ispindel->beercode);
+	logfile = xstrcat(logfile, (char *)" ");
+	logfile = xstrcat(logfile, ispindel->beername);
+	logfile = xstrcat(logfile, (char *)".log");
+
+	fp = fopen(logfile, "a");
+	if (fp) {
+	    fprintf(fp, "%s\n", line);
+	    fclose(fp);
+	} else {
+	    syslog(LOG_NOTICE, "cannot append to `%s'", logfile);
+	}
+
+	free(logfile);
+	logfile = NULL;
+	free(line);
+	line = NULL;
+	free(datetime);
+	datetime = NULL;
+    }
+}
+
+
+
+/*
+ * Process iSpindel MQTT message.
+ */
+void ispindel_birth_data(char *topic, char *payload)
+{
+    char		*message_type, *edge_node;
+
+    strtok(topic, "/"); // ignore namespace
+    strtok(NULL, "/");
+    message_type = strtok(NULL, "/");
+    edge_node = strtok(NULL, "/\0");
+
+    if (strcmp("DBIRTH", message_type) == 0) {
+	ispindel_set(edge_node, payload);
+    }
+}
+
+
+
+void ispindel_dump(sys_ispindel_list *ispindel)
+{
+    if (debug) {
+    	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        %.5f\n", ispindel->angle);
+	printf("temperature %.4f\n", ispindel->temperature);
+	printf("battery     %.6f\n", ispindel->battery);
+	printf("gravity     %.5f\n", ispindel->gravity);
+	printf("interval    %d\n", ispindel->interval);
+    }
+}
+
+

mercurial