1 /** |
1 /** |
2 * @file nodes.c |
2 * @file nodes.c |
3 * @brief Handle nodes status |
3 * @brief Handle nodes status |
4 * @author Michiel Broek <mbroek at mbse dot eu> |
4 * @author Michiel Broek <mbroek at mbse dot eu> |
5 * |
5 * |
6 * Copyright (C) 2018-2019 |
6 * Copyright (C) 2018-2020 |
7 * |
7 * |
8 * This file is part of the bms (Brewery Management System) |
8 * This file is part of the bms (Brewery Management System) |
9 * |
9 * |
10 * This is free software; you can redistribute it and/or modify it |
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 |
11 * under the terms of the GNU General Public License as published by the |
32 sys_node_list *nodes = NULL; |
32 sys_node_list *nodes = NULL; |
33 |
33 |
34 extern int debug; |
34 extern int debug; |
35 extern sys_fermenter_list *fermenters; |
35 extern sys_fermenter_list *fermenters; |
36 extern sys_co2meter_list *co2meters; |
36 extern sys_co2meter_list *co2meters; |
37 |
37 extern sys_ispindel_list *ispindels; |
38 |
38 |
39 |
39 |
40 void node_birth_data(char *topic, char *payload) |
40 void node_birth_data(char *topic, char *payload) |
41 { |
41 { |
42 struct json_object *jobj, *val, *metric, *metric2; |
42 struct json_object *jobj, *val, *metric, *metric2; |
80 node->firstseen = node->lastseen = time(NULL); |
80 node->firstseen = node->lastseen = time(NULL); |
81 node->temperature = node->humidity = node->barometer = 0.0; |
81 node->temperature = node->humidity = node->barometer = 0.0; |
82 node->gps_latitude = node->gps_longitude = node->gps_altitude = 0.0; |
82 node->gps_latitude = node->gps_longitude = node->gps_altitude = 0.0; |
83 node->net_address = node->net_ifname = NULL; |
83 node->net_address = node->net_ifname = NULL; |
84 node->net_rssi = 0; |
84 node->net_rssi = 0; |
|
85 node->interval = 300; |
85 } |
86 } |
86 |
87 |
87 /* |
88 /* |
88 * Process the JSON formatted payload. |
89 * Process the JSON formatted payload. |
89 * Update only the fields that are found in the payload. |
90 * Update only the fields that are found in the payload. |
108 if (json_object_object_get_ex(jobj, "metric", &metric)) { |
109 if (json_object_object_get_ex(jobj, "metric", &metric)) { |
109 if (json_object_object_get_ex(metric, "uuid", &val)) { |
110 if (json_object_object_get_ex(metric, "uuid", &val)) { |
110 if (node->uuid) |
111 if (node->uuid) |
111 free(node->uuid); |
112 free(node->uuid); |
112 node->uuid = xstrcpy((char *)json_object_get_string(val)); |
113 node->uuid = xstrcpy((char *)json_object_get_string(val)); |
|
114 } |
|
115 if (json_object_object_get_ex(metric, "interval", &val)) { |
|
116 node->interval = json_object_get_int(val); |
113 } |
117 } |
114 if (json_object_object_get_ex(metric, "properties", &metric2)) { |
118 if (json_object_object_get_ex(metric, "properties", &metric2)) { |
115 if (json_object_object_get_ex(metric2, "hardwaremake", &val)) { |
119 if (json_object_object_get_ex(metric2, "hardwaremake", &val)) { |
116 if (node->hardwaremake) |
120 if (node->hardwaremake) |
117 free(node->hardwaremake); |
121 free(node->hardwaremake); |
212 printf("first %ld last %ld\n", node->firstseen, node->lastseen); |
216 printf("first %ld last %ld\n", node->firstseen, node->lastseen); |
213 printf("THB %.2f %.2f %.2f\n", node->temperature, node->humidity, node->barometer); |
217 printf("THB %.2f %.2f %.2f\n", node->temperature, node->humidity, node->barometer); |
214 printf("GPS %.5f %.5f %.5f\n", node->gps_latitude, node->gps_longitude, node->gps_altitude); |
218 printf("GPS %.5f %.5f %.5f\n", node->gps_latitude, node->gps_longitude, node->gps_altitude); |
215 printf("net %s:%s\n", node->net_ifname, node->net_address); |
219 printf("net %s:%s\n", node->net_ifname, node->net_address); |
216 printf("rssi %d\n", node->net_rssi); |
220 printf("rssi %d\n", node->net_rssi); |
|
221 printf("interval %d\n", node->interval); |
217 } |
222 } |
218 } |
223 } |
219 |
224 |
220 |
225 |
221 |
226 |
245 void nodes_check_online() |
250 void nodes_check_online() |
246 { |
251 { |
247 sys_node_list *tmpn; |
252 sys_node_list *tmpn; |
248 sys_fermenter_list *tmpf; |
253 sys_fermenter_list *tmpf; |
249 sys_co2meter_list *tmpc; |
254 sys_co2meter_list *tmpc; |
|
255 sys_ispindel_list *tmpi; |
250 time_t now = time(NULL); |
256 time_t now = time(NULL); |
251 |
257 |
252 for (tmpn = nodes; tmpn; tmpn = tmpn->next) { |
258 for (tmpn = nodes; tmpn; tmpn = tmpn->next) { |
253 if (tmpn->online && ((now - tmpn->lastseen) > 600)) { |
259 // if (debug) |
254 syslog(LOG_NOTICE, "Timeout node `%s/%s'", tmpn->group_id, tmpn->node); |
260 // printf("%-20s online %s %ld %d\n", tmpn->node, tmpn->online ? "yes":"no ", tmpn->lastseen, tmpn->interval); |
|
261 if (tmpn->online && ((now - tmpn->lastseen) > (tmpn->interval * 2 + 5))) { // 2 times interval + 5 seconds |
|
262 syslog(LOG_NOTICE, "Timeout node `%s/%s' after %ld seconds", tmpn->group_id, tmpn->node, (now - tmpn->lastseen)); |
255 tmpn->online = false; |
263 tmpn->online = false; |
256 node_mysql_death(tmpn->node); |
264 node_mysql_death(tmpn->node); |
257 |
265 |
258 for (tmpf = fermenters; tmpf; tmpf = tmpf->next) { |
266 for (tmpf = fermenters; tmpf; tmpf = tmpf->next) { |
259 if (strcmp(tmpf->node, tmpn->node) == 0) { |
267 if (strcmp(tmpf->node, tmpn->node) == 0) { |
272 tmpc->online = false; |
280 tmpc->online = false; |
273 co2meter_mysql_death(tmpc->node, tmpc->alias); |
281 co2meter_mysql_death(tmpc->node, tmpc->alias); |
274 } |
282 } |
275 } |
283 } |
276 } |
284 } |
277 } |
285 |
278 } |
286 for (tmpi = ispindels; tmpi; tmpi = tmpi->next) { |
279 } |
287 if (strcmp(tmpi->node, tmpn->node) == 0) { |
280 |
288 if (tmpi->online) { |
281 |
289 syslog(LOG_NOTICE, "Timeout ispindel %s", tmpi->node); |
|
290 tmpi->online = false; |
|
291 ispindel_mysql_death(tmpi->node); |
|
292 } |
|
293 } |
|
294 } |
|
295 } |
|
296 } |
|
297 } |
|
298 |
|
299 |