thermferm/server.c

changeset 592
ff30227c0903
parent 591
95cf33f8021f
child 594
1904badedf8f
equal deleted inserted replaced
591:95cf33f8021f 592:ff30227c0903
249 249
250 250
251 int comp(ls_list **lsp1, ls_list **lsp2) 251 int comp(ls_list **lsp1, ls_list **lsp2)
252 { 252 {
253 return strcmp((*lsp1)->d_name, (*lsp2)->d_name); 253 return strcmp((*lsp1)->d_name, (*lsp2)->d_name);
254 }
255
256
257
258 /*
259 * ARCHIVE DIR
260 * ARCHIVE GET filename
261 * ARCHIVE LOG filename
262 * ARCHIVE HELP
263 */
264 int cmd_archive(char *buf)
265 {
266 char *opt, *param, *name = NULL, *filename = NULL, *logname = NULL, mbits[11], tstr[24];
267 DIR *dd;
268 FILE *fp;
269 struct dirent *result;
270 ls_list *lsx = NULL, *tmp;
271 struct stat sbuf;
272 struct tm *tbuf;
273 time_t ftime;
274 int found;
275 units_list *unit;
276
277
278 opt = strtok(buf, " \0");
279 opt = strtok(NULL, " \0");
280
281 if (opt == NULL) {
282 srv_send((char *)"501 Subcommand missing");
283 return 0;
284 }
285 param = strtok(NULL, "\0");
286
287 if (strcmp(opt, (char *)"HELP") == 0) {
288 srv_send((char *)"100 Help text follows:");
289 srv_send((char *)"Recognized commands:");
290 srv_send((char *)"ARCHIVE DIR Archived logfiles directory");
291 srv_send((char *)"ARCHIVE GET filename Archived logfile download");
292 srv_send((char *)"ARCHIVE LOG filename Archived logfile data in graphsteps");
293 srv_send((char *)".");
294 return 0;
295 }
296
297 if (strcmp(opt, (char *)"DIR") == 0) {
298
299 if (getenv((char *)"USER") == NULL) {
300 name = xstrcpy((char *)"/root");
301 } else {
302 name = xstrcpy(getenv((char *)"HOME"));
303 }
304 name = xstrcat(name, (char *)"/.thermferm/log/");
305
306 if ((dd = opendir(name))) {
307 for (;;) {
308 if (! (result = readdir(dd))) {
309 syslog(LOG_NOTICE, "readdir: error=%d", errno);
310 break;
311 }
312 if (result->d_name[0] != '.') {
313 filename = xstrcpy(name);
314 filename = xstrcat(filename, result->d_name);
315 /*
316 * Remove files from the list when they are in use
317 */
318 found = 0;
319 for (unit = Config.units; unit; unit = unit->next) {
320 if (unit->mode != UNITMODE_OFF) {
321 logname = xstrcpy(unit->product_code);
322 logname = xstrcat(logname, (char *)" ");
323 logname = xstrcat(logname, unit->product_name);
324 logname = xstrcat(logname, (char *)".log");
325 if (! strcmp(result->d_name, logname))
326 found = 1;
327 free(logname);
328 logname = NULL;
329 }
330 }
331 if ((found == 0) && ((stat(filename, &sbuf)) == 0)) {
332 fill_list(&lsx, result->d_name, sbuf.st_mode, sbuf.st_size, sbuf.st_mtime);
333 }
334 free(filename);
335 filename = NULL;
336 }
337 }
338 closedir(dd);
339 } else {
340 syslog(LOG_NOTICE, "opendir: \"%s\" error=%d", name, errno);
341 }
342
343 sort_list(&lsx);
344
345 srv_send((char *)"212 Archive directory follows:");
346 for (tmp = lsx; tmp; tmp = tmp->next) {
347 sprintf(mbits, "----------");
348 if (tmp->mode & S_IRUSR)
349 mbits[1] = 'r';
350 if (tmp->mode & S_IWUSR)
351 mbits[2] = 'w';
352 if (tmp->mode & S_IXUSR)
353 mbits[3] = 'x';
354 if (tmp->mode & S_IRGRP)
355 mbits[4] = 'r';
356 if (tmp->mode & S_IWGRP)
357 mbits[5] = 'w';
358 if (tmp->mode & S_IXGRP)
359 mbits[6] = 'x';
360 if (tmp->mode & S_IROTH)
361 mbits[7] = 'r';
362 if (tmp->mode & S_IWOTH)
363 mbits[8] = 'w';
364 if (tmp->mode & S_IXOTH)
365 mbits[9] = 'x';
366 ftime = tmp->mtime;
367 tbuf = localtime(&ftime);
368 sprintf(tstr, "%02d %s %04d %02d:%02d", tbuf->tm_mday, MONTH[tbuf->tm_mon], tbuf->tm_year+1900, tbuf->tm_hour, tbuf->tm_min);
369 srv_send((char *)"%s,%s,%d,%s", tmp->d_name, mbits, tmp->size, tstr);
370 }
371 srv_send((char *)".");
372 tidy_lslist(&lsx);
373
374 free(name);
375 name = NULL;
376 return 0;
377 }
378
379 if (param == NULL) {
380 srv_send((char *)"502 Parameter missing");
381 return 0;
382 }
383
384 if (strcmp(opt, (char *)"GET") == 0) {
385 if (getenv((char *)"USER") == NULL) {
386 name = xstrcpy((char *)"/root");
387 } else {
388 name = xstrcpy(getenv((char *)"HOME"));
389 }
390 name = xstrcat(name, (char *)"/.thermferm/log/");
391 name = xstrcat(name, param);
392
393 if ((fp = fopen(name, "r"))) {
394 char buffer[256];
395
396 srv_send((char *)"212 Archive file follows:");
397 while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) {
398 int i;
399
400 for (i = 0; i < strlen(buffer); i++) {
401 if (buffer[i] == '\n')
402 buffer[i] = '\0';
403 if (buffer[i] == '\r')
404 buffer[i] = '\0';
405 }
406 srv_send(buffer);
407 }
408 srv_send((char *)".");
409 fclose(fp);
410 } else {
411 srv_send((char *)"440 No such file");
412 }
413
414 free(name);
415 name = NULL;
416 return 0;
417 }
418
419 if (strcmp(opt, (char *)"LOG") == 0) {
420 if (getenv((char *)"USER") == NULL) {
421 name = xstrcpy((char *)"/root");
422 } else {
423 name = xstrcpy(getenv((char *)"HOME"));
424 }
425 name = xstrcat(name, (char *)"/.thermferm/log/");
426 name = xstrcat(name, param);
427
428 if ((fp = fopen(name, "r"))) {
429 char buffer[256], outbuf[256], q[5], hr[3];
430 char *date_n, *mode_n, *air_n, *beer_n, *target_lo_n, *target_hi_n, *heater_n, *cooler_n, *room_n, *chiller_n;
431 char *heater_u, *cooler_u;
432 int lines = 0, heater_l = 0, cooler_l = 0, h = 0, c = 0, heat_used = 0, cool_used = 0, graphstep = 0;
433 float room_t = 0.0;
434
435 srv_send((char *)"212 Logfile list follows:");
436 while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) {
437 lines++;
438 }
439 fseek(fp, 0L, SEEK_SET);
440 /*
441 * We have counted the lines in the logfile including the header lines.
442 * The header lines should be ignored but there are so few of them, we
443 * just include them in the total.
444 * Now find a reasonable interval of lines to sent to the client.
445 */
446 for (graphstep = 1; graphstep <= MAX_INTERVALS; graphstep++) {
447 if (lines < GRAPH_DATALINES[graphstep]) {
448 break;
449 }
450 }
451 if (graphstep > MAX_INTERVALS)
452 graphstep = MAX_INTERVALS;
453 syslog(LOG_NOTICE, "ARCHIVE LOG %s: lines=%d, interval=%d, graphstep=%d", param, lines, GRAPH_INTERVAL[graphstep], graphstep);
454
455 while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) {
456 /*
457 * 2014-11-15 18:39,BEER,20.312,19.750,20.0,0,NA,NA,NA,78105,NA,NA,18.000,20.1,5.312
458 * | | | | | | | | | | | | | | |
459 * date_n | | | | | | | | | | | | | |
460 * mode_n ----------+ | | | | | | | | | | | | |
461 * air_n -----------------+ | | | | | | | | | | | |
462 * beer_n -----------------------+ | | | | | | | | | | |
463 * target_lo_n ------------------------+ | | | | | | | | | |
464 * heater_n -------------------------------+ | | | | | | | | |
465 * cooler_n ---------------------------------+ | | | | | | | |
466 * not used ------------------------------------+ | | | | | | |
467 * not used ---------------------------------------+ | | | | | |
468 * heater_u --------------------------------------------+ | | | | |
469 * cooler_u ------------------------------------------------+ | | | |
470 * not used ---------------------------------------------------+ | | |
471 * room_n ----------------------------------------------------------+ | |
472 * target_hi_n -----------------------------------------------------------+ |
473 * chiller_n ------------------------------------------------------------------+
474 */
475 hr[0] = q[0] = buffer[11];
476 hr[1] = q[1] = buffer[12];
477 q[2] = buffer[14];
478 q[3] = buffer[15];
479 hr[2] = '\0';
480 buffer[strlen(buffer) -1] = '\0';
481 date_n = strtok(buffer, ",\0"); /* timestamp */
482 mode_n = strtok(NULL, ",\0"); /* unit mode */
483 air_n = strtok(NULL, ",\0"); /* air temp */
484 beer_n = strtok(NULL, ",\0"); /* beer temp */
485 target_lo_n = strtok(NULL, ",\0"); /* target low temp */
486 heater_n = strtok(NULL, ",\0"); /* current heater state */
487 cooler_n = strtok(NULL, ",\0"); /* current cooler state */
488 heater_u = strtok(NULL, ",\0"); /* current fan state */
489 heater_u = strtok(NULL, ",\0"); /* current door state */
490 heater_u = strtok(NULL, ",\0"); /* heater use counter */
491 cooler_u = strtok(NULL, ",\0"); /* cooler use counter */
492 room_n = strtok(NULL, ",\0"); /* fan use counter */
493 room_n = strtok(NULL, ",\0"); /* room temperature */
494 target_hi_n = strtok(NULL, ",\0"); /* target high temp */
495 chiller_n = strtok(NULL, ",\0"); /* chiller temp */
496
497 if (strncmp(mode_n, (char *)"Mode", 4)) {
498 /*
499 * Output a line at the right intervals
500 */
501 int hour = atoi(hr);
502 if (((graphstep == 1)) ||
503 ((graphstep == 2) && (q[3] == '0' || q[3] == '5')) ||
504 ((graphstep == 3) && ((q[2] == '0' && q[3] == '0') || (q[2] == '1' && q[3] == '5') || (q[2] == '3' && q[3] == '0') || (q[2] == '4' && q[3] == '5'))) ||
505 ((graphstep == 4) && ((q[2] == '0' && q[3] == '0') || (q[2] == '3' && q[3] == '0'))) ||
506 ((graphstep == 5) && (q[2] == '0' && q[3] == '0')) ||
507 ((graphstep == 6) && (hour % 2 == 0) && (q[2] == '0' && q[3] == '0')) || /* 120 minutes */
508 ((graphstep == 7) && (hour % 4 == 0) && (q[2] == '0' && q[3] == '0')) || /* 240 minutes */
509 ((graphstep >= 8) && (hour % 8 == 0) && (q[2] == '0' && q[3] == '0')) ) { /* 480 minutes */
510 heat_used = cool_used = 0;
511 if (heater_u && strcmp(heater_u, "NA") && (sscanf(heater_u, "%d", &h) == 1)) {
512 if (h && heater_l) {
513 heat_used = ((h - heater_l) * 100) / (GRAPH_INTERVAL[graphstep] * 60);
514 }
515 }
516 if (cooler_u && strcmp(cooler_u, "NA") && (sscanf(cooler_u, "%d", &c) == 1)) {
517 if (c && cooler_l) {
518 cool_used = ((c - cooler_l) * 100) / (GRAPH_INTERVAL[graphstep] * 60);
519 }
520 }
521 if (room_n)
522 sscanf(room_n, "%f", &room_t);
523 if (target_hi_n == NULL)
524 target_hi_n = target_lo_n;
525 snprintf(outbuf, 255, "%s,%s,%s,%s,%s,%s,%s,%d,%d,%.1f,%s,%s",
526 date_n, mode_n, air_n, beer_n, target_lo_n, heater_n, cooler_n, heat_used, cool_used, room_t,target_hi_n, chiller_n);
527 srv_send(outbuf);
528 if (heater_u && h && strcmp(heater_u, "NA"))
529 heater_l = h;
530 if (cooler_u && c & strcmp(cooler_u, "NA"))
531 cooler_l = c;
532 }
533 }
534 }
535
536 srv_send((char *)".");
537 fclose(fp);
538 } else {
539 srv_send((char *)"440 No such file");
540 }
541
542 free(name);
543 name = NULL;
544 }
545
546 return 0;
547 } 254 }
548 255
549 256
550 257
551 int delete_Device(char *uuid) 258 int delete_Device(char *uuid)
2417 if (rlen != -1) { 2124 if (rlen != -1) {
2418 if (strlen(buf)) { 2125 if (strlen(buf)) {
2419 /* 2126 /*
2420 * Process commands from the client 2127 * Process commands from the client
2421 */ 2128 */
2422 if (strncmp(buf, "ARCHIVE", 7) == 0) { 2129 if (strncmp(buf, "DEVICE", 6) == 0) {
2423 cmd_archive(buf);
2424
2425 } else if (strncmp(buf, "DEVICE", 6) == 0) {
2426 if (cmd_device(buf)) 2130 if (cmd_device(buf))
2427 wrconfig(); 2131 wrconfig();
2428 2132
2429 } else if (strncmp(buf, "GLOBAL", 6) == 0) { 2133 } else if (strncmp(buf, "GLOBAL", 6) == 0) {
2430 if (cmd_global(buf)) 2134 if (cmd_global(buf))
2433 } else if (strncmp(buf, "HELP", 4) == 0) { 2137 } else if (strncmp(buf, "HELP", 4) == 0) {
2434 srv_send((char *)"100 Help text follows"); 2138 srv_send((char *)"100 Help text follows");
2435 srv_send((char *)"Recognized commands:"); 2139 srv_send((char *)"Recognized commands:");
2436 srv_send((char *)""); 2140 srv_send((char *)"");
2437 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 2141 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
2438 srv_send((char *)"ARCHIVE <CMD> [parameters] Archive commands");
2439 srv_send((char *)"ARCHIVE HELP Archive help screen");
2440 srv_send((char *)"DEVICE <CMD> [parameters] Device commands"); 2142 srv_send((char *)"DEVICE <CMD> [parameters] Device commands");
2441 srv_send((char *)"DEVICE HELP Device help screen"); 2143 srv_send((char *)"DEVICE HELP Device help screen");
2442 srv_send((char *)"GLOBAL <CMD> [parameters] Global commands"); 2144 srv_send((char *)"GLOBAL <CMD> [parameters] Global commands");
2443 srv_send((char *)"GLOBAL HELP Global help screen"); 2145 srv_send((char *)"GLOBAL HELP Global help screen");
2444 srv_send((char *)"LIST <CMD> [parameters] List commands"); 2146 srv_send((char *)"LIST <CMD> [parameters] List commands");

mercurial