diff --git a/uno-stats-monitor/unomond/gather_stats.c b/uno-stats-monitor/unomond/gather_stats.c index 7577cee..e0d762c 100644 --- a/uno-stats-monitor/unomond/gather_stats.c +++ b/uno-stats-monitor/unomond/gather_stats.c @@ -1,14 +1,16 @@ /* - * UNO Monitor Daemon + * UNO Monitor Daemon v.0.1.0 * Kidacro + * https://kidacro.archamedis.net/git/kidacro/Arduino/src/branch/main/uno-stats-monitor * * gather_stats.c - retrieves stats from system * */ #include -#include #include +#include +#include #include #include #include @@ -16,6 +18,7 @@ #define MAX_ENTRIES 10 // from monitor_daemon.c +bool file_exists(const char *filename); void send_stats(); // local function prototypes @@ -120,7 +123,7 @@ void get_stats() snprintf(line_1,sizeof(line_1),"#1%s%% %sC %sM@",cpuload,cputemp,freemem); snprintf(line_2,sizeof(line_2),"#2%s@",trim(freespace)); - snprintf(line_3,sizeof(line_3),"#3%s@",cpuload); + snprintf(line_3,sizeof(line_3),"#-%s@",cpuload); send_stats(line_1,line_2,line_3); @@ -192,11 +195,16 @@ void get_cpu_temp() FILE* ptr; char str[10]; + // check if file exists + if(!file_exists(cpu_temp_file)) { + return; + } + // opening file in readonly mode ptr = fopen(&*cpu_temp_file, "r"); if(NULL == ptr) { - fprintf(log_stream,"File %s can't be opened!\n",cpu_temp_file); + fprintf(log_stream,"File cpu_temp_file: %s, can't be opened!\n",cpu_temp_file); return; } diff --git a/uno-stats-monitor/unomond/monitor_daemon.c b/uno-stats-monitor/unomond/monitor_daemon.c index d9219b9..40100c9 100644 --- a/uno-stats-monitor/unomond/monitor_daemon.c +++ b/uno-stats-monitor/unomond/monitor_daemon.c @@ -1,6 +1,7 @@ /* - * UNO Monitor Daemon + * UNO Monitor Daemon v.0.1.0 * Kidacro + * https://kidacro.archamedis.net/git/kidacro/Arduino/src/branch/main/uno-stats-monitor * * monitor_daemon.c - Sends and Receives commands to UNO Monitor over serial connection * @@ -9,18 +10,25 @@ * End char is: '@' * 2nd char denotes which line number/mode to use * + * Setting Schema: + * LCDLength:LCDDelay:LEDBrightness:LEDDelay + * 16:5:1:3 + * * Example: * Line 1: #1Archamedis Status@ * Line 2: #299% free / etc.@ - * LAVG 3: #324@ + * LAVG -: #324@ + * LSET 0: #16:5:1:3@ * * Output Schema: * Multimedia Controls use single characters to denote which button was pressed * */ +// C library #include #include +#include #include #include #include @@ -32,6 +40,9 @@ #include #include #include +#include + +// external libs #include #define MAX_ENTRIES 10 @@ -42,7 +53,7 @@ int running = 0; char *conf_file_name = "unomond.conf"; char *pid_file_name = "/tmp/unomond.pid"; int pid_fd = -1; -const char *app_name = "UnomonD"; +const char *app_name = "UnomonD v.0.1.0"; FILE *log_stream; char *log_file_name = NULL; int serial_port; @@ -50,15 +61,17 @@ struct termios tty; struct timeval __millis_start; // config file settings -int delay = 10000; +int delay = 5000; int line_length = 16; int line_count = 2; +int lcd_delay = 5; +int led_brightness = 5; +int led_delay = 3; const char *cpu_temp_file = ""; -const char *cpu_fanspeed_file; +const char *cpu_fanspeed_file = ""; char *drive_free_space[MAX_ENTRIES]; int drive_free_space_count; const char *ttydevice = "/dev/ttyACM0"; -const char *logfile = ""; const char *ircmd_P = ""; // power const char *ircmd_M = ""; // mute const char *ircmd_m = ""; // mode @@ -86,6 +99,8 @@ const char *ircmd_Z = ""; // other button pressed // function prototypes void init_millis(); unsigned long int millis(); +char* timestamp(); +bool file_exists(const char *filename); int read_conf_file(int reload); void handle_signal(int sig); static void daemonize(); @@ -93,28 +108,55 @@ void print_help(void); int serial_open_port(); int listen_server(); void send_stats(); +void send_settings(); +void log_method(); // from gather_stats.c void get_stats(); // local functions -void init_millis() { +void init_millis() +{ gettimeofday(&__millis_start, NULL); } -unsigned long int millis() { +unsigned long int millis() +{ long mtime, seconds, useconds; struct timeval end; gettimeofday(&end, NULL); seconds = end.tv_sec - __millis_start.tv_sec; useconds = end.tv_usec - __millis_start.tv_usec; - mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5; return mtime; } +char* timestamp() +{ + unsigned size = 300; + char* buffer = malloc(size); + //char time_s; + time_t ltime; /* calendar time */ + ltime=time(NULL); /* get current cal time */ + //time_s = sprintf("%s",asctime( localtime(<ime) ) ); + snprintf(buffer, size, "%s", asctime( localtime(<ime) )); + return buffer; +} + +bool file_exists(const char *filename) +{ + FILE *fp = fopen(filename, "r"); + bool is_exist = false; + if(fp != NULL) { + is_exist = true; + fclose(fp); // close the file + } + return is_exist; +} + // read from config file -int read_conf_file(int reload) { +int read_conf_file(int reload) +{ int ret = -1, n = 0; config_t cfg; config_setting_t *drive_free_space_entries; @@ -147,22 +189,36 @@ int read_conf_file(int reload) { const char *myircmd_R; const char *myircmd_Z; - config_init(&cfg); if(conf_file_name == NULL) { - fprintf(log_stream, "Can not open configuration file %s.\n",conf_file_name); - syslog(LOG_INFO, "Can not open configuration file %s.",conf_file_name); - return(1); + syslog(LOG_INFO, "Configuration file: %s is empty or not valid.\n",conf_file_name); + return(EXIT_FAILURE); } - // read the file. if there is an error, report it and exit + // check if conf file exists + if(!file_exists(conf_file_name)) { + return(EXIT_FAILURE); + } + + // read the file + config_init(&cfg); if(!config_read_file(&cfg, conf_file_name)) { - fprintf(log_stream, "%s:%d - %s\n", config_error_file(&cfg), + syslog(LOG_INFO, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); - syslog(LOG_INFO, "Can not open configuration file %s, exiting.",conf_file_name); + syslog(LOG_INFO, "Can not open configuration file: %s.\n",conf_file_name); return(EXIT_FAILURE); } + // logfile (lookup logfile first and if found do a log_method to reload it) + if(config_lookup_string(&cfg, "logfile", &mylogfile)) { + log_file_name = strdup(mylogfile); + log_method(); + fprintf(log_stream, "Config: Using 'logfile': %s\n", mylogfile); + } + else { + syslog(LOG_INFO, "No 'logfile' setting in configuration file, using default stderr output.\n"); + } + // load the base config // delay if(config_lookup_int(&cfg, "delay", &delay)) { @@ -181,15 +237,6 @@ int read_conf_file(int reload) { fprintf(log_stream, "No 'tty' setting in configuration file, using default tty of %s.\n",ttydevice); } - // logfile - if(config_lookup_string(&cfg, "logfile", &mylogfile)) { - logfile = strdup(mylogfile); - fprintf(log_stream, "Config: Using 'logfile': %s\n",logfile); - } - else { - fprintf(log_stream, "No 'logfile' setting in configuration file, using default stderr output.\n"); - } - // line_length if(config_lookup_int(&cfg, "line_length", &line_length)) { fprintf(log_stream, "Config: Using 'line_length': %i\n",line_length); @@ -206,6 +253,30 @@ int read_conf_file(int reload) { fprintf(log_stream, "No 'line_count' setting in configuration file, using default line_count of %i.\n",line_count); } + // led_brightness + if(config_lookup_int(&cfg, "led_brightness", &led_brightness)) { + fprintf(log_stream, "Config: Using 'led_brightness': %i\n",led_brightness); + } + else { + fprintf(log_stream, "No 'led_brightness' setting in configuration file, using default led_brightness of %i.\n",led_brightness); + } + + // led_delay + if(config_lookup_int(&cfg, "led_delay", &led_delay)) { + fprintf(log_stream, "Config: Using 'led_delay': %i\n",led_delay); + } + else { + fprintf(log_stream, "No 'led_delay' setting in configuration file, using default led_delay of %i.\n",led_delay); + } + + // lcd_delay + if(config_lookup_int(&cfg, "lcd_delay", &lcd_delay)) { + fprintf(log_stream, "Config: Using 'lcd_delay': %i\n",lcd_delay); + } + else { + fprintf(log_stream, "No 'lcd_delay' setting in configuration file, using default lcd_delay of %i.\n",lcd_delay); + } + // cpu stats settings if(config_lookup_string(&cfg, "cpu_temp_file", &mycpu_temp_file)) { cpu_temp_file = strdup(mycpu_temp_file); @@ -277,7 +348,6 @@ void handle_signal(int sig) if(pid_fd != -1) { lock_result = lockf(pid_fd, F_ULOCK, 0); if(lock_result < 0) { - fprintf(log_stream,"Lockfile could not be unlocked.\n"); syslog(LOG_INFO, "Lockfile could not be unlocked."); } close(pid_fd); @@ -296,12 +366,10 @@ void handle_signal(int sig) return; } else if (sig == SIGHUP) { - //fprintf(log_stream, "Reloading daemon config file ...\n"); syslog(LOG_INFO, "Reloading daemon config file ..."); read_conf_file(1); } else if (sig == SIGCHLD) { - //fprintf(log_stream, "Received SIGCHLD signal\n"); syslog(LOG_INFO, "Received SIGCHLD signal"); } } @@ -317,17 +385,17 @@ static void daemonize() pid = fork(); /* An error occurred */ - if (pid < 0) { + if(pid < 0) { exit(EXIT_FAILURE); } /* Success: Let the parent terminate */ - if (pid > 0) { + if(pid > 0) { exit(EXIT_SUCCESS); } /* On success: The child process becomes session leader */ - if (setsid() < 0) { + if(setsid() < 0) { exit(EXIT_FAILURE); } @@ -338,12 +406,12 @@ static void daemonize() pid = fork(); /* An error occurred */ - if (pid < 0) { + if(pid < 0) { exit(EXIT_FAILURE); } /* Success: Let the parent terminate */ - if (pid > 0) { + if(pid > 0) { exit(EXIT_SUCCESS); } @@ -354,7 +422,6 @@ static void daemonize() /* or another appropriated directory */ chdir_result = chdir("/"); if(chdir_result <0) { - //fprintf(log_stream,"Could not change to our working directory.\n"); syslog(LOG_INFO, "Could not change to our working directory."); } @@ -388,10 +455,8 @@ static void daemonize() /* Write PID to lockfile */ write_result = write(pid_fd, str, strlen(str)); if(write_result < 0) { - //fprintf(log_stream,"PID could not be written to lockfile.\n"); syslog(LOG_INFO, "PID could not be written to lockfile."); } - } } @@ -461,27 +526,17 @@ int serial_open_port() /* Server */ int listen_server() { - // Allocate memory for read buffer, set size according to your needs char read_buf [2]; - - // Normally you wouldn't do this memset() call, but since we will just receive - // ASCII data for this example, we'll set everything to 0 so we can - // call printf() easily. + int exec_result = 0; memset(&read_buf, '\0', sizeof(read_buf)); - - // Read bytes. The behaviour of read() (e.g. does it block?, - // how long does it block for?) depends on the configuration - // settings above, specifically VMIN and VTIME int num_bytes = read(serial_port, &read_buf, sizeof(read_buf)); - // n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error. + // may be 0 if no bytes were received, and can also be -1 to signal an error. if(num_bytes < 0) { fprintf(log_stream, "Error reading: %s\n", strerror(errno)); return 1; } - int exec_result = 0; - // do stuff goes here // switch on read_buf // input proto: PMmpbfe-+ru0123456789RZ @@ -559,24 +614,44 @@ void send_stats(char *line_1, char *line_2, char *line_3) return; } +/* Send settings to receiver */ +// Setting Schema: +// LCDLength:LCDDelay:LEDBrightness:LEDDelay +// 16:5:1:3 + +void send_settings() { + char myline[16]; + unsigned int mylen = 0; + int write_result = 0; + + sprintf(myline,"#0%i:%i:%i:%i@",line_length,lcd_delay,led_brightness,led_delay); + mylen = strlen(myline); + write_result = write(serial_port, myline, mylen); + + if(write_result < 0) { + fprintf(log_stream, "Writing settings to serial report resulted in %i error. Size of message: %i\n", write_result, mylen); + syslog(LOG_INFO, "Writing settings to serial report resulted in %i error.",write_result); + } + + return; +} + /* Daemon log method */ void log_method() { + // close log file, if its open + if(log_stream != stderr && log_stream != NULL) { + fclose(log_stream); + } + // command line logfile takes precedence - if(log_file_name != NULL) { + if(log_file_name != NULL && file_exists(log_file_name)) { log_stream = fopen(log_file_name, "a+"); if(log_stream == NULL) { syslog(LOG_ERR, "Can not open log file: %s, error: %s", log_file_name, strerror(errno)); log_stream = stderr; // stdout; + return; } - } - - // config logfile - else if(logfile != NULL) { - log_stream = fopen(logfile, "a+"); - if(log_stream == NULL) { - syslog(LOG_ERR, "Can not open log file: %s, error: %s", logfile, strerror(errno)); - log_stream = stderr; // stdout; - } + syslog(LOG_INFO, "Using logfile: %s\n",log_file_name); } // use stderr as failback @@ -604,6 +679,8 @@ int main(int argc, char *argv[]) char *mytty = NULL; int start_daemonized = 0; + //fprintf(log_stream,"Timestamp %s\n",timestamp()); + /* Open system log and write startup message to it */ openlog(argv[0], LOG_PID|LOG_CONS, LOG_DAEMON); syslog(LOG_INFO, "Started %s", app_name); @@ -612,7 +689,7 @@ int main(int argc, char *argv[]) signal(SIGINT, handle_signal); signal(SIGHUP, handle_signal); - // define default log method + /* Set default log method */ log_method(); /* Read configuration from config file @@ -669,6 +746,7 @@ int main(int argc, char *argv[]) /* Main loop */ serial_open_port(); + send_settings(); init_millis(); while(running == 1) { listen_server(); // listen for IR events (blocks for 1 second at a time) @@ -685,12 +763,12 @@ int main(int argc, char *argv[]) close(serial_port); /* Close log file, when it is used. */ - if(log_stream != stderr) { + if(log_stream != stderr && log_stream != NULL) { fclose(log_stream); } /* Write system log and close it. */ - syslog(LOG_INFO, "Stopped %s\n", app_name); + syslog(LOG_INFO, "Stopped %s.\n", app_name); closelog(); return EXIT_SUCCESS;