/****************************************************************************
- * 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
****************************************************************************/
-/* 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)
*/
#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)
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;
if (data_idx > 0) {
data[data_idx] = c;
if (c == '$') {
+ data[data_idx + 1] = '\0';
data_idx = 0;
return 1;
}
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;
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);
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 */
} 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 */
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++;