Add logging to file separated in "data" and "info" parts
authorNathael Pajani <nathael.pajani@ed3l.fr>
Fri, 24 Nov 2023 22:55:58 +0000 (23:55 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Fri, 24 Nov 2023 22:55:58 +0000 (23:55 +0100)
host/scialys_decode/main.c

index c108487..2b98901 100644 (file)
@@ -1,10 +1,10 @@
 /****************************************************************************
- *  Get data from sensors and decode
+ *  Receive and decode data from Scialys module
  *
  *   main.c
  *
  *
- * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ * Copyright 2013-2023 Nathael Pajani <nathael.pajani@ed3l.fr>
  *
  *
  * This program is free software: you can redistribute it and/or modify
@@ -23,9 +23,9 @@
  ****************************************************************************/
 
 
-/* this protocol handler is designed to run on a host replacing the DTPlug,
- * but should be easy to use as a source for the protocol handling code for
- * the DTPlug itself.
+/*
+ * This host app decodes the frames continuously sent by the scialys module on his
+ * serial line (UART)
  */
 
 
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <errno.h>
 #include <getopt.h>
+#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/select.h>
 #include "serial_utils.h"
 
 
-#define BUF_SIZE  100
-
 #define PROG_NAME  "Sensors polling and decode"
-#define VERSION  "0.1"
+#define VERSION  "0.2"
 
 
 void help(char *prog_name)
@@ -57,12 +56,15 @@ void help(char *prog_name)
        fprintf(stderr, "Usage: %s [options]\n" \
                "  Available options:\n" \
                "  \t -d | --device : Serial device to use for serial communication with the module\n" \
+               "  \t -l | --log : Base filename to use for log files\n" \
                "  \t -h | --help : Print this help\n" \
                "  \t -v | --version : Print programm version\n" \
                "  All other arguments are data for the command, handled depending on the command.\n", prog_name);
        fprintf(stderr, "-----------------------------------------------------------------------\n");
 }
 
+#define MAX_LOGNAME_LEN 200
+#define BUF_SIZE  100
 #define MSG_LEN  150
 char data[MSG_LEN];
 int data_idx = 0;
@@ -80,6 +82,7 @@ int protocol_decode(char c)
        if (data_idx > 0) {
                data[data_idx] = c;
                if (c == '$') {
+                       data[data_idx + 1] = '\0';
                        data_idx = 0;
                        return 1;
                }
@@ -97,18 +100,28 @@ int main(int argc, char* argv[])
        char* device = NULL;
        int slave_fd = 0;
 
+       /* Log file */
+       char* log_base_name = NULL;
+       int data_log_fd = 0;
+       int info_log_fd = 0;
+
+       /* Timestamp */
+       struct timeval now;
+       int start_sec = 0;
+
        while(1) {
                int option_index = 0;
                int c = 0;
 
                struct option long_options[] = {
                        {"device", required_argument, 0, 'd'},
+                       {"log", required_argument, 0, 'l'},
                        {"help", no_argument, 0, 'h'},
                        {"version", no_argument, 0, 'v'},
                        {0, 0, 0, 0}
                };
 
-               c = getopt_long(argc, argv, "d:hv", long_options, &option_index);
+               c = getopt_long(argc, argv, "d:l:hv", long_options, &option_index);
 
                /* no more options to parse */
                if (c == -1) break;
@@ -119,6 +132,11 @@ int main(int argc, char* argv[])
                                device = optarg;
                                break;
 
+                       /* l, base name for log file */
+                       case 'l':
+                               log_base_name = optarg;
+                               break;
+
                        /* v, version */
                        case 'v':
                                printf("%s Version %s\n", PROG_NAME, VERSION);
@@ -148,16 +166,37 @@ int main(int argc, char* argv[])
                return -2;
        }
 
+       /* Log files ? */
+       if (log_base_name != NULL) {
+               char name[MAX_LOGNAME_LEN];
+               mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+
+               snprintf(name, MAX_LOGNAME_LEN, "%s.data", log_base_name);
+               data_log_fd = open(name, O_RDWR|O_CREAT|O_APPEND, mode);
+               if (data_log_fd <= 0) {
+                       printf("Unable to open Data log file '%s' : %s", name, strerror(errno));
+               }
+               snprintf(name, MAX_LOGNAME_LEN, "Mode Loop Sol Home Teau Tpow Tdis Pmin/Max ZC Cmd/act Fan/fo Terr TMos OV Dis Force Manual\n");
+               write(data_log_fd, name, strlen(name));
+               snprintf(name, MAX_LOGNAME_LEN, "%s.info", log_base_name);
+               info_log_fd = open(name, O_RDWR|O_CREAT|O_APPEND, mode);
+               if (info_log_fd <= 0) {
+                       printf("Unable to open Info log file '%s' : %s", name, strerror(errno));
+               }
+       }
+
+       /* Save start second */
+       gettimeofday(&now, NULL);
+       start_sec = now.tv_sec;
+
+
        /* ************************************************* */
        /* And never stop handling data ! */
        while (1) {
                int len = 0, ret = 0;
-               struct timeval now;
                char buf[BUF_SIZE];
                int idx = 0;
-
-               /* Send periodic requests for temperature */
-               gettimeofday(&now, NULL);
+               int sec = 0, msec = 0;
 
                memset(buf, 0, BUF_SIZE);
                /* Get serial data and try to build a packet */
@@ -181,8 +220,30 @@ int main(int argc, char* argv[])
                } else {
                        write(2, buf, len);
                }
+
+               /* timestamp */
+               gettimeofday(&now, NULL);
+               sec = now.tv_sec - start_sec;
+               msec = now.tv_usec / 1000;
+
                while (idx < len) {
+                       /* Extract frames from data stream */
                        ret = protocol_decode(buf[idx]);
+                       /* Log ? */
+                       if ((info_log_fd > 0) && (ret == 0) && (data_idx == 0)) {
+                               static char last_logged_char = '\0';
+                               /* Add timestamps */
+                               if ((last_logged_char == '\n') && (buf[idx] != '\n')) {
+                                       char ts[20];
+                                       snprintf(ts, 13, "% 5d.%03d : ", sec, msec);
+                                       write(info_log_fd, ts, 12);
+                               }
+                               /* Do not log empty lines */
+                               if ((buf[idx] != '\n') || (last_logged_char != '\n')) {
+                                       write(info_log_fd, (buf + idx), 1);
+                                       last_logged_char = buf[idx];
+                               }
+                       }
                        /* Check return code to know if we have a valid packet */
                        if (ret == 1) {
                                /* Valid packet received, parse data */
@@ -220,6 +281,15 @@ int main(int argc, char* argv[])
                                                        external_disable, forced_heater_mode, manual_activation_request,
                                                        error_shutdown, temp_shutdown, overvoltage);
                                printf("\e[K\n");
+
+                               /* Log ? */
+                               if (data_log_fd > 0) {
+                                       char ts[20];
+                                       snprintf(ts, 13, "% 5d.%03d : ", sec, msec);
+                                       write(data_log_fd, ts, 12);
+                                       write(data_log_fd, data, strnlen(data, MSG_LEN));
+                                       write(data_log_fd, "\n", 1);
+                               }
                        }
 
                        idx++;