add working through CAN-to-socket proxy

This commit is contained in:
Edward Emelianov 2022-02-03 16:02:33 +03:00
parent 13de663270
commit 7344a6a332
7 changed files with 65 additions and 46 deletions

View File

@ -1,26 +1,30 @@
### Serial interface commands (ends with '\n'), small letter for only ## Serial interface commands (ends with '\n'), small letter for only local processing:
local processing: - **0...7** send message to Nth controller, not broadcast (after number should be CAN command)
- **0...7** send message to Nth controller, not broadcast (after numb - **@** set/reset debug mode
er should be CAN command) - **a** get raw ADC values
- **a** get raw ADC values - **B** send dummy CAN messages to broadcast address
- **B** send dummy CAN messages to broadcast address - **b** get/set CAN bus baudrate
- **c** show coefficients for all thermosensors - **c** show coefficients for all thermosensors
- **D** send dummy CAN messages to master (0) address - **D** send dummy CAN messages to master (0) address
- **d** get current CAN address of device
- **Ee** end temperature scan - **Ee** end temperature scan
- **Ff** turn sensors off - **Ff** turn sensors off
- **g** get last CAN address - **g** group (sniffer) CAN mode (print to USB terminal all incoming CAN messages with alien IDs)
- **Hh** switch I2C to high speed (100kHz) - **Hh** switch I2C to high speed (100kHz)
- **i** reinit CAN with new address (if changed) - **Ii** (re)init sensors
- **Jj** get MCU temperature - **Jj** get MCU temperature
- **Kk** get values of U and I - **Kk** get values of U and I
- **Ll** switch I2C to low speed (default, 10kHz) - **Ll** switch I2C to low speed (default, 10kHz)
- **Mm** change master id to 0 (**m**) / broadcast (**M**) - **Mm** change master id to 0 (**m**) / broadcast (**M**)
- **Oo** turn onboard diagnostic LEDs **O**n or **o**ff (both commands - **N** get build number
are local!) - **Oo** turn onboard diagnostic LEDs **O**n or **o**ff (both commands are local!)
- **P** ping everyone over CAN - **P** ping everyone over CAN
- **Qq** get system time
- **Rr** reinit I2C - **Rr** reinit I2C
- **Ss** start temperature scan - **s** send CAN message (format: ID data[0..8], dec, 0x - hex, 0b - binary)
- **Tt** start single temperature measurement - **Tt** start single temperature measurement
- **u** check CAN bus status for errors - **u** unique ID (default) CAN mode
- **Vv** very low speed - **Vv** very low speed
- **Z** get sensors state over CAN - **Xx** go into temperature scan mode
- **Yy** get sensors state over CAN (data format: 3 - state, 4,5 - presense mask [0,1], 6 - npresent, 7 - ntempmeasured
- **z** check CAN status for errors

View File

@ -62,6 +62,7 @@ static myoption cmdlnopts[] = {
{"testadjfile",NO_ARGS, NULL, 'T', arg_int, APTR(&G.testadjfile),_("test format of file with T adjustements")}, {"testadjfile",NO_ARGS, NULL, 'T', arg_int, APTR(&G.testadjfile),_("test format of file with T adjustements")},
{"adjname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.adjfilename),_("name of adjustements file (default: tempadj.txt)")}, {"adjname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.adjfilename),_("name of adjustements file (default: tempadj.txt)")},
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfilename),_("name of PID file (default: " DEFAULT_PIDFILE ")")}, {"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfilename),_("name of PID file (default: " DEFAULT_PIDFILE ")")},
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verblevel), _("increase log file verbose level (default: warn)")},
//{"dumpoff", NO_ARGS, NULL, 'd', arg_string, APTR(&G.dumpoff), _("dump sensors data & turn all OFF until next request")}, //{"dumpoff", NO_ARGS, NULL, 'd', arg_string, APTR(&G.dumpoff), _("dump sensors data & turn all OFF until next request")},
end_option end_option
}; };

View File

@ -27,17 +27,16 @@
* here are some typedef's for global data * here are some typedef's for global data
*/ */
typedef struct{ typedef struct{
char *sockname; // server's UNIX socket name
char *port; // port to connect
//int terminal; // run as terminal
char *savepath; // path where data & graphical files would be saved
int makegraphs; // ==1 to make graphics with gnuplot int makegraphs; // ==1 to make graphics with gnuplot
int rest_pars_num; // number of rest parameters int rest_pars_num; // number of rest parameters
char** rest_pars; // the rest parameters: array of char* (path to logfile and thrash)
int testadjfile; // test format of file with adjustments int testadjfile; // test format of file with adjustments
int verblevel; // increase log file verbose level (default: warn)
char *sockname; // server's UNIX socket name
char *port; // port to connect
char *savepath; // path where data & graphical files would be saved
char *adjfilename; // name of adjustements file char *adjfilename; // name of adjustements file
char *pidfilename; // name of PID file char *pidfilename; // name of PID file
//int dumpoff; // dump sensors data & turn all OFF until next request char **rest_pars; // the rest parameters: array of char* (path to logfile and thrash)
} glob_pars; } glob_pars;

View File

@ -93,8 +93,11 @@ int main(int argc, char **argv){
} }
return 1; return 1;
} }
if(G->rest_pars_num) if(G->rest_pars_num){
OPENLOG(G->rest_pars[0], LOGLEVEL_DBG, 1); sl_loglevel loglevel = LOGLEVEL_WARN + G->verblevel; // default log level
if(loglevel > LOGLEVEL_ANY) loglevel = LOGLEVEL_ANY;
OPENLOG(G->rest_pars[0], loglevel, 1);
}
// ignore almost all possible signals // ignore almost all possible signals
for(int sig = 0; sig < 256; ++sig) signal(sig, repsig); for(int sig = 0; sig < 256; ++sig) signal(sig, repsig);
signal(SIGTERM, signals); // kill (-15) - quit signal(SIGTERM, signals); // kill (-15) - quit
@ -106,9 +109,9 @@ int main(int argc, char **argv){
signal(SIGUSR1, refreshAdj); // refresh adjustements signal(SIGUSR1, refreshAdj); // refresh adjustements
signal(SIGUSR2, logT); // print all current temperatures into logfile and turn off sensors signal(SIGUSR2, logT); // print all current temperatures into logfile and turn off sensors
#ifndef EBUG #ifndef EBUG
if(daemon(1, 0)){ /* if(daemon(1, 0)){
ERR("daemon()"); ERR("daemon()");
} }*/
while(1){ // guard for dead processes while(1){ // guard for dead processes
childpid = fork(); childpid = fork();
if(childpid){ if(childpid){
@ -124,7 +127,7 @@ int main(int argc, char **argv){
} }
#endif #endif
DBG("sockname: %s", G->sockname); DBG("sockname: %s", G->sockname);
if(!try_connect(G->sockname)) ERR("Can't connect to UNIX socket"); if(!try_connect(G->sockname)) ERRX("Can't connect to UNIX socket");
if(check_sensors()){ if(check_sensors()){
LOGWARN("No CAN-controllers detected"); LOGWARN("No CAN-controllers detected");
if(!poll_sensors(0)){ // there's not main controller connected to given terminal if(!poll_sensors(0)){ // there's not main controller connected to given terminal

View File

@ -326,16 +326,23 @@ static void process_T(){
// calculate mean // calculate mean
double Tmed = quick_select(arr, Num); double Tmed = quick_select(arr, Num);
double Tbot = Tmed - 10., Ttop = Tmed + 10.; double Tbot = Tmed - 10., Ttop = Tmed + 10.;
DBG("Got %d values, Tmed=%g", Num, Tmed); DBG("Got %d values, Tmed=%g, tmeasmax=%zd", Num, Tmed, tmeasmax);
// throw out all more than +-10degrC and calculate meanT // throw out all more than +-10degrC and calculate meanT
Num = 0; Num = 0;
double Tsum = 0.; double Tsum = 0.;
// remove bad/old values of N2 controller
for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){
if(tmeasmax - tmeasured[p][N][0] > OLDESTTM){ // not longer than 3 minutes ago!
t_last[p][N][0] = -300.;
}
}
for(i = 1; i <= NCTRLR_MAX; ++i){ for(i = 1; i <= NCTRLR_MAX; ++i){
for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){ for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){
double T = t_last[p][N][i]; double T = t_last[p][N][i];
if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > 1800){ // not longer than 3 minutes ago! if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > OLDESTTM){ // not longer than 3 minutes ago!
t_last[p][N][i] = -300.; t_last[p][N][i] = -300.;
}else{ }else{
DBG("t_last[%d][%d][%d]=%.1f, measuredt=%zd", p, N, i, T, tmeasured[p][N][i]);
++Num; Tsum += T; ++Num; Tsum += T;
Tmean[p][N][i] += T; Tmean[p][N][i] += T;
++Nmean[p][N][i]; ++Nmean[p][N][i];
@ -371,6 +378,7 @@ static void daemon_(int sock){
ERR("pthread_create()"); ERR("pthread_create()");
} }
double tgot = 0.;//, tlastoff = dtime(); double tgot = 0.;//, tlastoff = dtime();
char bufs[3][BUFLEN]; // temporary buffers: T0, T1, T2
do{ do{
if(pthread_kill(sock_thread, 0) == ESRCH){ // died if(pthread_kill(sock_thread, 0) == ESRCH){ // died
WARNX("Sockets thread died"); WARNX("Sockets thread died");
@ -383,17 +391,13 @@ static void daemon_(int sock){
if(TurnOff){ if(TurnOff){
TurnOff = FALSE; TurnOff = FALSE;
turn_all_off(); turn_all_off();
//tlastoff = dtime(); }
}/*
if(dtime() - tlastoff > T_OFF_INTERVAL){
turn_all_off();
tlastoff = dtime();
}*/
if(dtime() - tgot < T_INTERVAL) continue; if(dtime() - tgot < T_INTERVAL) continue;
// get data // get data
int i; int i;
char bufs[3][BUFLEN]; // temporary buffers: T0, T1, T2 char *bptrs[3] = {bufs[0], bufs[1], bufs[2]};
char *ptrs[3] = {bufs[0], bufs[1], bufs[2]}; bzero(bufs, sizeof(bufs));
DBG("STARTING vals: BUF0:\n%s\nBUF1:\n%s\nBUF2:\n%s", bufs[0],bufs[1],bufs[2]);
size_t lens[3] = {BUFLEN, BUFLEN, BUFLEN}; // free space size_t lens[3] = {BUFLEN, BUFLEN, BUFLEN}; // free space
tgot = dtime(); tgot = dtime();
process_T(); // get new temperatures & throw out bad results process_T(); // get new temperatures & throw out bad results
@ -403,18 +407,18 @@ static void daemon_(int sock){
double T = t_last[p][N][i]; double T = t_last[p][N][i];
char **buf; char **buf;
size_t *len; size_t *len;
//DBG("T%d [%d][%d] = %g",i, p,N,T);
if(T > -100. && T < 100.){ // fill buffer if(T > -100. && T < 100.){ // fill buffer
DBG("T%d [%d][%d] = %g",i, p,N,T);
size_t l; size_t l;
if(i == 0){ if(i == 0){
buf = &ptrs[2]; len = &lens[2]; buf = &bptrs[2]; len = &lens[2];
// Nsens Npair T time // Nsens Npair T time
l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", N, p, T, l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", N, p, T,
tmeasured[p][N][i]); tmeasured[p][N][i]);
}else{ }else{
const sensor_data *sdata = get_sensor_location(i, N, p); const sensor_data *sdata = get_sensor_location(i, N, p);
if(!sdata) continue; // wrong sensor number??? if(!sdata) continue; // wrong sensor number???
buf = &ptrs[sdata->Z]; len = &lens[sdata->Z]; buf = &bptrs[sdata->Z]; len = &lens[sdata->Z];
// iNp x y T(corrected) time // iNp x y T(corrected) time
l = snprintf(*buf, *len, "%d%d%d\t%d\t%d\t%.2f\t%ld\n", i, N, p, l = snprintf(*buf, *len, "%d%d%d\t%d\t%d\t%.2f\t%ld\n", i, N, p,
sdata->X, sdata->Y, T - sdata->dt - sdata->Tadj, tmeasured[p][N][i]); sdata->X, sdata->Y, T - sdata->dt - sdata->Tadj, tmeasured[p][N][i]);
@ -424,7 +428,7 @@ static void daemon_(int sock){
} }
} }
} }
//DBG("BUF0:\n%s\nBUF1:\n%s\nBUF2:\n%s", bufs[0],bufs[1],bufs[2]); DBG("BUF0:\n%s\nBUF1:\n%s\nBUF2:\n%s", bufs[0],bufs[1],bufs[2]);
// copy temporary buffers to main // copy temporary buffers to main
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
memcpy(strT, bufs, sizeof(strT)); memcpy(strT, bufs, sizeof(strT));

View File

@ -102,7 +102,15 @@ int try_connect(char *path){
if(!path) return FALSE; if(!path) return FALSE;
struct sockaddr_un saddr = {0}; struct sockaddr_un saddr = {0};
saddr.sun_family = AF_UNIX; saddr.sun_family = AF_UNIX;
strncpy(saddr.sun_path, path, 106); // if sun_path[0] == 0 we don't create a file if(*path == 0){ // if sun_path[0] == 0 then don't create a file
DBG("convert name");
saddr.sun_path[0] = 0;
strncpy(saddr.sun_path+1, path+1, 106);
}else if(strncmp("\\0", path, 2) == 0){
DBG("convert name");
saddr.sun_path[0] = 0;
strncpy(saddr.sun_path+1, path+2, 105);
}else strncpy(saddr.sun_path, path, 107);
if((sock = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0){ // or SOCK_STREAM? if((sock = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0){ // or SOCK_STREAM?
WARN("socket()"); WARN("socket()");
LOGERR("socket()"); LOGERR("socket()");

View File

@ -30,12 +30,12 @@
#define WAIT_TMOUT (0.5) #define WAIT_TMOUT (0.5)
// Main controller polling timeout - 1 second // Main controller polling timeout - 1 second
#define POLLING_TMOUT (1.0) #define POLLING_TMOUT (1.0)
// Thermal polling timeout: 5 seconds // Thermal polling timeout: 1.5 seconds
#define T_POLLING_TMOUT (5.0) #define T_POLLING_TMOUT (1.5)
// T measurement time interval - 30 seconds // T measurement time interval - 30 seconds
#define T_INTERVAL (30.0) #define T_INTERVAL (30.0)
// Interval of turning sensors off - 3 days // interval (in seconds) to remove too old measurements (if sensor not available now)
#define T_OFF_INTERVAL (259200.) #define OLDESTTM (180)
// amount of measurement to plot mean graphs // amount of measurement to plot mean graphs
#define GRAPHS_AMOUNT (15) #define GRAPHS_AMOUNT (15)