bmsd/ispindels.c

branch
stable
changeset 665
4d01937ae7af
parent 654
0aef416dbceb
child 675
a27af02ab16a
equal deleted inserted replaced
521:9d1aa6f3a4da 665:4d01937ae7af
1 /**
2 * @file ispindels.c
3 * @brief Handle ispindels data
4 * @author Michiel Broek <mbroek at mbse dot eu>
5 *
6 * Copyright (C) 2019-2020
7 *
8 * This file is part of the bms (Brewery Management System)
9 *
10 * This is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2, or (at your option) any
13 * later version.
14 *
15 * bms is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ThermFerm; see the file COPYING. If not, write to the Free
22 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 */
24
25
26 #include "bms.h"
27 #include "xutil.h"
28 #include "ispindels.h"
29 #include "mysql.h"
30 #include "nodes.h"
31
32
33 sys_ispindel_list *ispindels = NULL;
34
35 extern int debug;
36 extern sys_config Config;
37 extern MYSQL *con;
38 extern MYSQL_RES *res_set;
39 extern MYSQL_ROW row;
40
41
42
43 void ispindel_set(char *node, char *payload)
44 {
45 sys_ispindel_list *ispindel, *tmpp;
46 struct json_object *jobj, *metric, *val;
47 bool new_ispindel = true;
48 char *datetime, buf[65], *line, *logfile;
49 struct tm *mytime;
50 time_t timestamp;
51 FILE *fp;
52
53 // if (debug)
54 // printf("ispindel_set: %s %s\n", node, payload);
55
56 /*
57 * Search ispindel record in the memory array and use it if found.
58 */
59 if (ispindels) {
60 for (tmpp = ispindels; tmpp; tmpp = tmpp->next) {
61 if (strcmp(tmpp->node, node) == 0) {
62 new_ispindel = false;
63 ispindel = tmpp;
64 break;
65 }
66 }
67 }
68
69 // if (debug)
70 // printf("new_ispindel %s\n", new_ispindel ? "true":"false");
71
72 /*
73 * Allocate new ispindel if not yet known.
74 */
75 if (new_ispindel) {
76 ispindel = (sys_ispindel_list *)malloc(sizeof(sys_ispindel_list));
77 memset(ispindel, 0, sizeof(sys_ispindel_list));
78 ispindel->node = xstrcpy(node);
79 ispindel->mode = xstrcpy((char *)"OFF");
80 }
81
82 if (! ispindel->online) {
83 ispindel->online = true;
84 syslog(LOG_NOTICE, "Online ispindel %s mode %s", node, ispindel->mode);
85 }
86
87 /*
88 * Process the JSON formatted payload.
89 * Update only the fields that are found in the payload.
90 */
91 jobj = json_tokener_parse(payload);
92
93 if (json_object_object_get_ex(jobj, "unit", &metric)) {
94 if (json_object_object_get_ex(metric, "uuid", &val)) {
95 if (ispindel->uuid)
96 free(ispindel->uuid);
97 ispindel->uuid = xstrcpy((char *)json_object_get_string(val));
98 }
99 if (json_object_object_get_ex(metric, "alias", &val)) {
100 if (ispindel->alias)
101 free(ispindel->alias);
102 ispindel->alias = xstrcpy((char *)json_object_get_string(val));
103 }
104 if (json_object_object_get_ex(metric, "alarm", &val)) {
105 ispindel->alarm = json_object_get_int(val);
106 }
107 if (json_object_object_get_ex(metric, "interval", &val)) {
108 ispindel->interval = json_object_get_int(val);
109 }
110 if (json_object_object_get_ex(metric, "angle", &val)) {
111 ispindel->angle = json_object_get_double(val);
112 }
113 if (json_object_object_get_ex(metric, "temperature", &val)) {
114 ispindel->temperature = json_object_get_double(val);
115 }
116 if (json_object_object_get_ex(metric, "battery", &val)) {
117 ispindel->battery = json_object_get_double(val);
118 }
119 if (json_object_object_get_ex(metric, "gravity", &val)) {
120 ispindel->gravity = json_object_get_double(val);
121 }
122 }
123
124 // ispindel_dump(ispindel);
125
126 if (new_ispindel) {
127 if (ispindels == NULL) {
128 ispindels = ispindel;
129 } else {
130 for (tmpp = ispindels; tmpp; tmpp = tmpp->next) {
131 if (tmpp->next == NULL) {
132 tmpp->next = ispindel;
133 break;
134 }
135 }
136 }
137 ispindel_mysql_insert(ispindel);
138 } else {
139 ispindel_mysql_update(ispindel);
140 }
141
142 /*
143 * The data is complete, see if we can write a log entry.
144 */
145 if (ispindel->beercode && strlen(ispindel->beercode) && ispindel->beername && strlen(ispindel->beername) &&
146 ispindel->online && (strcmp(ispindel->mode, (char *)"ON") == 0)) {
147 datetime = malloc(72);
148 timestamp = time(NULL);
149 mytime = localtime(&timestamp);
150 snprintf(datetime, 72, "%04d-%02d-%02d %02d:%02d:%02d",
151 mytime->tm_year + 1900, mytime->tm_mon + 1, mytime->tm_mday, mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
152
153 line = xstrcpy(datetime);
154 line = xstrcat(line, (char *)",");
155 snprintf(buf, 64, "%.4f", ispindel->temperature);
156 line = xstrcat(line, buf);
157 line = xstrcat(line, (char *)",");
158 snprintf(buf, 64, "%.5f", ispindel->gravity);
159 line = xstrcat(line, buf);
160 line = xstrcat(line, (char *)",");
161 // snprintf(buf, 64, "%.5f", 1 + (ispindel->gravity / (258.6 - ((ispindel->gravity / 258.2) * 227.1))));
162 snprintf(buf, 64, "%.5f", 1.00001 + (0.0038661 * ispindel->gravity) + (1.3488e-5 * ispindel->gravity * ispindel->gravity) +
163 (4.3074e-8 * ispindel->gravity * ispindel->gravity * ispindel->gravity));
164 line = xstrcat(line, buf);
165 line = xstrcat(line, (char *)",");
166 snprintf(buf, 64, "%.6f", ispindel->battery);
167 line = xstrcat(line, buf);
168 line = xstrcat(line, (char *)",");
169 snprintf(buf, 64, "%.5f", ispindel->angle);
170 line = xstrcat(line, buf);
171 line = xstrcat(line, (char *)",");
172 snprintf(buf, 64, "%d", ispindel->interval);
173 line = xstrcat(line, buf);
174 line = xstrcat(line, (char *)",");
175 line = xstrcat(line, ispindel->uuid);
176
177 /*
178 * Build logfile name
179 */
180 logfile = xstrcpy(Config.web_root);
181 logfile = xstrcat(logfile, (char *)"/log/ispindel/");
182 logfile = xstrcat(logfile, ispindel->beercode);
183 logfile = xstrcat(logfile, (char *)" ");
184 logfile = xstrcat(logfile, ispindel->beername);
185 logfile = xstrcat(logfile, (char *)".log");
186
187 fp = fopen(logfile, "a");
188 if (fp) {
189 fprintf(fp, "%s\n", line);
190 fclose(fp);
191 } else {
192 syslog(LOG_NOTICE, "cannot append to `%s'", logfile);
193 }
194
195 free(logfile);
196 logfile = NULL;
197 free(line);
198 line = NULL;
199 free(datetime);
200 datetime = NULL;
201 }
202 }
203
204
205
206 /*
207 * Process iSpindel MQTT message.
208 */
209 void ispindel_birth_data(char *topic, char *payload)
210 {
211 char *message_type, *edge_node;
212
213 strtok(topic, "/"); // ignore namespace
214 strtok(NULL, "/");
215 message_type = strtok(NULL, "/");
216 edge_node = strtok(NULL, "/\0");
217
218 if (strcmp("DBIRTH", message_type) == 0) {
219 ispindel_set(edge_node, payload);
220 }
221 }
222
223
224
225 void ispindel_dump(sys_ispindel_list *ispindel)
226 {
227 if (debug) {
228 printf("node/alias %s / %s\n", ispindel->node, ispindel->alias);
229 printf("uuid %s\n", ispindel->uuid);
230 printf("online %s\n", ispindel->online ? "yes":"no");
231 printf("mode %s\n", ispindel->mode);
232 printf("product %s / %s\n", ispindel->beercode, ispindel->beername);
233 printf("tilt %.5f\n", ispindel->angle);
234 printf("temperature %.4f\n", ispindel->temperature);
235 printf("battery %.6f\n", ispindel->battery);
236 printf("gravity %.5f\n", ispindel->gravity);
237 printf("interval %d\n", ispindel->interval);
238 }
239 }
240
241

mercurial