mirror of
https://github.com/eddyem/tsys01.git
synced 2026-02-01 04:45:05 +03:00
start to fix errors. 1. Tadj added
This commit is contained in:
parent
f34c50bbaf
commit
fef588a7d1
File diff suppressed because it is too large
Load Diff
127
src/netdaemon/checkfile.c
Normal file
127
src/netdaemon/checkfile.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* daemon.c - functions for running in background like a daemon
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <dirent.h> // opendir
|
||||
#include "checkfile.h"
|
||||
#include "usefull_macros.h"
|
||||
|
||||
/**
|
||||
* @brief readPSname - read process name from /proc/PID/cmdline
|
||||
* @param pid - PID of interesting process
|
||||
* @return filename or NULL if not found
|
||||
* don't use this function twice for different names without copying
|
||||
* its returning by strdup, because `name` contains in static array
|
||||
*/
|
||||
char *readPSname(pid_t pid){
|
||||
static char name[PATH_MAX];
|
||||
char *pp = name, byte, path[PATH_MAX];
|
||||
FILE *file;
|
||||
int cntr = 0;
|
||||
size_t sz;
|
||||
snprintf(path, PATH_MAX, PROC_BASE "/%d/cmdline", pid);
|
||||
file = fopen(path, "r");
|
||||
if(!file) return NULL; // there's no such file
|
||||
do{ // read basename
|
||||
sz = fread(&byte, 1, 1, file);
|
||||
if(sz != 1) break;
|
||||
if(byte != '/') *pp++ = byte;
|
||||
else{
|
||||
pp = name;
|
||||
cntr = 0;
|
||||
}
|
||||
}while(byte && cntr++ < PATH_MAX-1);
|
||||
name[cntr] = 0;
|
||||
fclose(file);
|
||||
return name;
|
||||
}
|
||||
|
||||
static char *pidfilename_ = NULL; // store the name of pidfile here
|
||||
|
||||
/**
|
||||
* check wether there is a same running process
|
||||
* exit if there is a running process or error
|
||||
* Checking have 3 steps:
|
||||
* 1) lock executable file
|
||||
* 2) check pidfile (if you run a copy?)
|
||||
* 3) check /proc for executables with the same name (no/wrong pidfile)
|
||||
* @param pidfilename - name of pidfile or NULL if none
|
||||
* @return 0 if all OK or PID of first running process found
|
||||
*/
|
||||
pid_t check4running(char *pidfilename){
|
||||
DIR *dir;
|
||||
FILE *pidfile;
|
||||
struct dirent *de;
|
||||
struct stat s_buf;
|
||||
pid_t pid = 0, self;
|
||||
char *name, *myname;
|
||||
self = getpid(); // get self PID
|
||||
if(!(dir = opendir(PROC_BASE))){ // open /proc directory
|
||||
ERR(PROC_BASE);
|
||||
}
|
||||
if(!(name = readPSname(self))){ // error reading self name
|
||||
ERR("Can't read self name");
|
||||
}
|
||||
myname = strdup(name);
|
||||
if(pidfilename && stat(pidfilename, &s_buf) == 0){ // pidfile exists
|
||||
pidfile = fopen(pidfilename, "r");
|
||||
if(pidfile){
|
||||
if(fscanf(pidfile, "%d", &pid) > 0){ // read PID of (possibly) running process
|
||||
if((name = readPSname(pid)) && strncmp(name, myname, 255) == 0){
|
||||
fclose(pidfile);
|
||||
goto procfound;
|
||||
}
|
||||
}
|
||||
fclose(pidfile);
|
||||
}
|
||||
}
|
||||
// There is no pidfile or it consists a wrong record
|
||||
while((de = readdir(dir))){ // scan /proc
|
||||
if(!(pid = (pid_t)atoi(de->d_name)) || pid == self) // pass non-PID files and self
|
||||
continue;
|
||||
if((name = readPSname(pid)) && strncmp(name, myname, 255) == 0)
|
||||
goto procfound;
|
||||
}
|
||||
pid = 0; // OK, not found -> create pid-file if need
|
||||
if(pidfilename){
|
||||
pidfile = fopen(pidfilename, "w");
|
||||
if(!pidfile){
|
||||
WARN("Can't open PID file");
|
||||
}else{
|
||||
fprintf(pidfile, "%d\n", self); // write self PID to pidfile
|
||||
fclose(pidfile);
|
||||
if(pidfilename_) FREE(pidfilename_);
|
||||
pidfilename_ = strdup(pidfilename);
|
||||
}
|
||||
}
|
||||
procfound:
|
||||
closedir(dir);
|
||||
free(myname);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unlink_pidfile - remove pidfile @ exit
|
||||
*/
|
||||
void unlink_pidfile(){
|
||||
if(!pidfilename_) return;
|
||||
unlink(pidfilename_);
|
||||
FREE(pidfilename_);
|
||||
}
|
||||
39
src/netdaemon/checkfile.h
Normal file
39
src/netdaemon/checkfile.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the Zphocus project.
|
||||
* Copyright 2019 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef CHECKFILE_H__
|
||||
#define CHECKFILE_H__
|
||||
|
||||
#include <unistd.h> // getpid, unlink
|
||||
|
||||
#ifndef PROC_BASE
|
||||
#define PROC_BASE "/proc"
|
||||
#endif
|
||||
#ifndef WEAK
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#endif
|
||||
|
||||
// check that our process is exclusive
|
||||
pid_t check4running(char *pidfilename);
|
||||
// read name of process by its PID
|
||||
char *readPSname(pid_t pid);
|
||||
void unlink_pidfile();
|
||||
|
||||
|
||||
#endif // CHECKFILE_H__
|
||||
@ -35,6 +35,7 @@ static glob_pars G;
|
||||
// default values for Gdefault & help
|
||||
#define DEFAULT_COMDEV "/dev/ttyUSB0"
|
||||
#define DEFAULT_PORT "4444"
|
||||
#define DEFAULT_PIDFILE "/tmp/TSYS01daemon.pid"
|
||||
|
||||
// DEFAULTS
|
||||
// default global parameters
|
||||
@ -45,7 +46,9 @@ glob_pars const Gdefault = {
|
||||
.savepath = NULL,
|
||||
.makegraphs = 0,
|
||||
.rest_pars = NULL,
|
||||
.rest_pars_num = 0
|
||||
.rest_pars_num = 0,
|
||||
.adjfilename = "tempadj.txt",
|
||||
.pidfilename = DEFAULT_PIDFILE
|
||||
};
|
||||
|
||||
/*
|
||||
@ -60,6 +63,9 @@ myoption cmdlnopts[] = {
|
||||
{"terminal",NO_ARGS, NULL, 't', arg_int, APTR(&G.terminal), _("run as terminal")},
|
||||
{"savepath",NEED_ARG, NULL, 's', arg_string, APTR(&G.savepath), _("path where files would be saved (if none - don't save)")},
|
||||
{"graphplot",NO_ARGS, NULL, 'g', arg_int, APTR(&G.makegraphs),_("make graphics with gnuplot")},
|
||||
{"testadjfile",NO_ARGS, NULL, 'T', arg_int, APTR(&G.testadjfile),_("test format of file with T adjustements and force running proces to re-read it")},
|
||||
{"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 ")")},
|
||||
end_option
|
||||
};
|
||||
|
||||
|
||||
@ -37,6 +37,9 @@ typedef struct{
|
||||
int makegraphs; // ==1 to make graphics with gnuplot
|
||||
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
|
||||
char *adjfilename; // name of adjustements file
|
||||
char *pidfilename; // name of PID file
|
||||
} glob_pars;
|
||||
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ static int formfile(char *fname, double data[2][NCHANNEL_MAX+1][NCTRLR_MAX+1], i
|
||||
const sensor_data *sdata = get_sensor_location(i, N, p);
|
||||
if(!sdata) continue;
|
||||
if(Z != sdata->Z) continue;
|
||||
fprintf(F, "%d\t%d\t%.2f\n", sdata->X, sdata->Y, T - sdata->dt);
|
||||
fprintf(F, "%d\t%d\t%.2f\n", sdata->X, sdata->Y, T - sdata->dt - sdata->Tadj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,15 +18,18 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
#include "usefull_macros.h"
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h> // wait
|
||||
#include <sys/prctl.h> //prctl
|
||||
#include "checkfile.h"
|
||||
#include "cmdlnopts.h"
|
||||
#include "socket.h"
|
||||
#include "usefull_macros.h"
|
||||
|
||||
glob_pars *G;
|
||||
glob_pars *G; // non-static: some another files should know about it!
|
||||
static pid_t childpid = 0; // PID of child - to kill it if need
|
||||
|
||||
// default signals handler
|
||||
void signals(int signo){
|
||||
restore_console();
|
||||
restore_tty();
|
||||
@ -34,35 +37,64 @@ void signals(int signo){
|
||||
exit(signo);
|
||||
}
|
||||
|
||||
// SIGUSR1 handler - re-read Tadj file
|
||||
void refreshAdj(_U_ int signo){
|
||||
DBG("refresh adj");
|
||||
if(childpid){ // I am a master
|
||||
putlog("Force child %d to re-read adj-file", childpid);
|
||||
kill(childpid, SIGUSR1);
|
||||
}else{ // I am a child
|
||||
putlog("Re-read adj-file");
|
||||
read_adj_file(G->adjfilename);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
initial_setup();
|
||||
signal(SIGTERM, signals); // kill (-15) - quit
|
||||
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||
signal(SIGINT, signals); // ctrl+C - quit
|
||||
signal(SIGQUIT, signals); // ctrl+\ - quit
|
||||
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
|
||||
G = parse_args(argc, argv);
|
||||
if(G->rest_pars_num)
|
||||
openlogfile(G->rest_pars[0]);
|
||||
if(G->makegraphs && !G->savepath){
|
||||
ERRX(_("Point the path to graphical files"));
|
||||
}
|
||||
#ifndef EBUG
|
||||
if(daemon(1, 0)){
|
||||
ERR("daemon()");
|
||||
DBG("t=%d", G->testadjfile);
|
||||
int raf = read_adj_file(G->adjfilename);
|
||||
pid_t runningproc = check4running(G->pidfilename);
|
||||
if(G->testadjfile){
|
||||
if(raf == 0){
|
||||
green("Format of file %s is right\n", G->adjfilename);
|
||||
if(runningproc){ // fore running process to re-read it
|
||||
kill(runningproc, SIGUSR1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
while(1){ // guard for dead processes
|
||||
pid_t childpid = fork();
|
||||
if(childpid){
|
||||
putlog("create child with PID %d\n", childpid);
|
||||
DBG("Created child with PID %d\n", childpid);
|
||||
wait(NULL);
|
||||
putlog("child %d died\n", childpid);
|
||||
WARNX("Child %d died\n", childpid);
|
||||
sleep(1);
|
||||
}else{
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
||||
break; // go out to normal functional
|
||||
if(runningproc) ERRX("Found running process, pid=%d.", runningproc);
|
||||
signal(SIGTERM, signals); // kill (-15) - quit
|
||||
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||
signal(SIGINT, signals); // ctrl+C - quit
|
||||
signal(SIGQUIT, signals); // ctrl+\ - quit
|
||||
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
|
||||
signal(SIGUSR1, refreshAdj); // refresh adjustements
|
||||
#ifndef EBUG
|
||||
if(!G->terminal){
|
||||
if(daemon(1, 0)){
|
||||
ERR("daemon()");
|
||||
}
|
||||
while(1){ // guard for dead processes
|
||||
childpid = fork();
|
||||
if(childpid){
|
||||
putlog("create child with PID %d\n", childpid);
|
||||
DBG("Created child with PID %d\n", childpid);
|
||||
wait(NULL);
|
||||
putlog("child %d died\n", childpid);
|
||||
WARNX("Child %d died\n", childpid);
|
||||
sleep(1);
|
||||
}else{
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
||||
break; // go out to normal functional
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "sens_place.h"
|
||||
#include "stdbool.h"
|
||||
#include "usefull_macros.h"
|
||||
#include "math.h" // fabs
|
||||
|
||||
/**
|
||||
Sensor place Dt X Y Z
|
||||
@ -104,97 +105,96 @@
|
||||
571 18 0.02 13 3 0
|
||||
*/
|
||||
|
||||
static const sensor_data sensors[] = {
|
||||
static sensor_data sensors[NSENSORS] = {
|
||||
// {Dt,X,Y,Z},
|
||||
{-0.07, 19, 7, 0}, // 0
|
||||
{0.03, 20, 0, 0}, // 1
|
||||
{0.03, 19, -7, 0}, // 2
|
||||
{-0.05, 17, -10, 1}, // 3
|
||||
{0.02, 17, -22, 0}, // 4
|
||||
{-0.03, 15, -13, 0}, // 5
|
||||
{0.02, 22, -17, 0}, // 6
|
||||
{-0.09, 24, -14, 1}, // 7
|
||||
{0.03, 25, -10, 0}, // 8
|
||||
{0.02, 27, -4, 0}, // 9
|
||||
{-0.01, 27, 4, 0}, // 10
|
||||
{-0.09, 25, 10, 0}, // 11
|
||||
{0.07, 22, 17, 0}, // 12
|
||||
{0, 24, 14, 1}, // 13
|
||||
{0.02, 10, 25, 0}, // 14
|
||||
{0.08, 17, 22, 0}, // 15
|
||||
{-0.01, 4, 27, 0}, // 16
|
||||
{-0.03, 0, 27, 1}, // 17
|
||||
{0.04, -4, 27, 0}, // 18
|
||||
{-0.01, -10, 25, 0}, // 19
|
||||
{-0.02, -17, 22, 0}, // 20
|
||||
{-0.04, -22, 17, 0}, // 21
|
||||
{0.03, -25, 10, 0}, // 22
|
||||
{-0.03, -24, 14, 1}, // 23
|
||||
{-0.03, -27, -4, 0}, // 24
|
||||
{0.03, -27, 4, 0}, // 25
|
||||
{-0.05, -25, -10, 0}, // 26
|
||||
{0, -24, -14, 1}, // 27
|
||||
{0.03, -22, -17, 0}, // 28
|
||||
{-0.05, -17, -22, 0}, // 29
|
||||
{-0.02, -10, -25, 0}, // 30
|
||||
{0.04, -4, -27, 0}, // 31
|
||||
{0.12, -3, -20, 0}, // 32
|
||||
{0, -10, -17, 0}, // 33
|
||||
{-0.08, -15, -13, 0}, // 34
|
||||
{-0.08, -17, -10, 1}, // 35
|
||||
{-0.1, -19, -7, 0}, // 36
|
||||
{-0.04, -20, 0, 0}, // 37
|
||||
{-0.08, -19, 7, 0}, // 38
|
||||
{0.03, -17, 10, 1}, // 39
|
||||
{0.11, -15, 13, 0}, // 40
|
||||
{0.07, -10, 17, 0}, // 41
|
||||
{0.09, -3, 20, 0}, // 42
|
||||
{-0.09, 0, 20, 1}, // 43
|
||||
{-0.1, 3, 20, 0}, // 44
|
||||
{0.04, 10, 17, 0}, // 45
|
||||
{0.05, 15, 13, 0}, // 46
|
||||
{-0.04, 17, 10, 1}, // 47
|
||||
{0.01, 9, 9, 0}, // 48
|
||||
{-0.04, 11, 7, 1}, // 49
|
||||
{0.01, 3, 13, 0}, // 50
|
||||
{-0.04, 0, 13, 1}, // 51
|
||||
{0.14, -9, 9, 0}, // 52
|
||||
{0, -3, 13, 0}, // 53
|
||||
{0.07, -13, 3, 0}, // 54
|
||||
{-0.02, -11, 7, 1}, // 55
|
||||
{0.04, -13, -3, 0}, // 56
|
||||
{-0.06, -11, -7, 1}, // 57
|
||||
{0.01, -9, -9, 0}, // 58
|
||||
{0.08, -3, -13, 0}, // 59
|
||||
{-0.09, 3, -13, 0}, // 60
|
||||
{-0.04, 0, -13, 1}, // 61
|
||||
{0.06, 3, -20, 0}, // 62
|
||||
{-0.05, 0, -20, 1}, // 63
|
||||
{0.05, 4, -27, 0}, // 64
|
||||
{-0.08, 0, -27, 1}, // 65
|
||||
{0.1, 10, -17, 0}, // 66
|
||||
{-0.05, 10, -25, 0}, // 67
|
||||
{0, 9, -9, 0}, // 68
|
||||
{0.01, 11, -7, 1}, // 69
|
||||
{0, 3, -5, 0}, // 70
|
||||
{-0.02, 0, -6, 1}, // 71
|
||||
{0.05, -3, -5, 0}, // 72
|
||||
{-0.03, -6, 0, 0}, // 73
|
||||
{0.03, -3, 5, 0}, // 74
|
||||
{0.06, 0, 6, 1}, // 75
|
||||
{0, 3, 5, 0}, // 76
|
||||
{-0.06, 6, 0, 0}, // 77
|
||||
{-0.07, 13, -3, 0}, // 78
|
||||
{0.02, 13, 3, 0}, // 79
|
||||
{-0.07, 19, 7, 0, 0}, // 0
|
||||
{0.03, 20, 0, 0, 0}, // 1
|
||||
{0.03, 19, -7, 0, 0}, // 2
|
||||
{-0.05, 17, -10, 1, 0}, // 3
|
||||
{0.02, 17, -22, 0, 0}, // 4
|
||||
{-0.03, 15, -13, 0, 0}, // 5
|
||||
{0.02, 22, -17, 0, 0}, // 6
|
||||
{-0.09, 24, -14, 1, 0}, // 7
|
||||
{0.03, 25, -10, 0, 0}, // 8
|
||||
{0.02, 27, -4, 0, 0}, // 9
|
||||
{-0.01, 27, 4, 0, 0}, // 10
|
||||
{-0.09, 25, 10, 0, 0}, // 11
|
||||
{0.07, 22, 17, 0, 0}, // 12
|
||||
{0, 24, 14, 1, 0}, // 13
|
||||
{0.02, 10, 25, 0, 0}, // 14
|
||||
{0.08, 17, 22, 0, 0}, // 15
|
||||
{-0.01, 4, 27, 0, 0}, // 16
|
||||
{-0.03, 0, 27, 1, 0}, // 17
|
||||
{0.04, -4, 27, 0, 0}, // 18
|
||||
{-0.01, -10, 25, 0, 0}, // 19
|
||||
{-0.02, -17, 22, 0, 0}, // 20
|
||||
{-0.04, -22, 17, 0, 0}, // 21
|
||||
{0.03, -25, 10, 0, 0}, // 22
|
||||
{-0.03, -24, 14, 1, 0}, // 23
|
||||
{-0.03, -27, -4, 0, 0}, // 24
|
||||
{0.03, -27, 4, 0, 0}, // 25
|
||||
{-0.05, -25, -10, 0, 0}, // 26
|
||||
{0, -24, -14, 1, 0}, // 27
|
||||
{0.03, -22, -17, 0, 0}, // 28
|
||||
{-0.05, -17, -22, 0, 0}, // 29
|
||||
{-0.02, -10, -25, 0, 0}, // 30
|
||||
{0.04, -4, -27, 0, 0}, // 31
|
||||
{0.12, -3, -20, 0, 0}, // 32
|
||||
{0, -10, -17, 0, 0}, // 33
|
||||
{-0.08, -15, -13, 0, 0}, // 34
|
||||
{-0.08, -17, -10, 1, 0}, // 35
|
||||
{-0.1, -19, -7, 0, 0}, // 36
|
||||
{-0.04, -20, 0, 0, 0}, // 37
|
||||
{-0.08, -19, 7, 0, 0}, // 38
|
||||
{0.03, -17, 10, 1, 0}, // 39
|
||||
{0.11, -15, 13, 0, 0}, // 40
|
||||
{0.07, -10, 17, 0, 0}, // 41
|
||||
{0.09, -3, 20, 0, 0}, // 42
|
||||
{-0.09, 0, 20, 1, 0}, // 43
|
||||
{-0.1, 3, 20, 0, 0}, // 44
|
||||
{0.04, 10, 17, 0, 0}, // 45
|
||||
{0.05, 15, 13, 0, 0}, // 46
|
||||
{-0.04, 17, 10, 1, 0}, // 47
|
||||
{0.01, 9, 9, 0, 0}, // 48
|
||||
{-0.04, 11, 7, 1, 0}, // 49
|
||||
{0.01, 3, 13, 0, 0}, // 50
|
||||
{-0.04, 0, 13, 1, 0}, // 51
|
||||
{0.14, -9, 9, 0, 0}, // 52
|
||||
{0, -3, 13, 0, 0}, // 53
|
||||
{0.07, -13, 3, 0, 0}, // 54
|
||||
{-0.02, -11, 7, 1, 0}, // 55
|
||||
{0.04, -13, -3, 0, 0}, // 56
|
||||
{-0.06, -11, -7, 1, 0}, // 57
|
||||
{0.01, -9, -9, 0, 0}, // 58
|
||||
{0.08, -3, -13, 0, 0}, // 59
|
||||
{-0.09, 3, -13, 0, 0}, // 60
|
||||
{-0.04, 0, -13, 1, 0}, // 61
|
||||
{0.06, 3, -20, 0, 0}, // 62
|
||||
{-0.05, 0, -20, 1, 0}, // 63
|
||||
{0.05, 4, -27, 0, 0}, // 64
|
||||
{-0.08, 0, -27, 1, 0}, // 65
|
||||
{0.1, 10, -17, 0, 0}, // 66
|
||||
{-0.05, 10, -25, 0, 0}, // 67
|
||||
{0, 9, -9, 0, 0}, // 68
|
||||
{0.01, 11, -7, 1, 0}, // 69
|
||||
{0, 3, -5, 0, 0}, // 70
|
||||
{-0.02, 0, -6, 1, 0}, // 71
|
||||
{0.05, -3, -5, 0, 0}, // 72
|
||||
{-0.03, -6, 0, 0, 0}, // 73
|
||||
{0.03, -3, 5, 0, 0}, // 74
|
||||
{0.06, 0, 6, 1, 0}, // 75
|
||||
{0, 3, 5, 0, 0}, // 76
|
||||
{-0.06, 6, 0, 0, 0}, // 77
|
||||
{-0.07, 13, -3, 0, 0}, // 78
|
||||
{0.02, 13, 3, 0, 0}, // 79
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief get_sensor_location - return pointer to sensor_data for given sensor
|
||||
* @brief get_sensor_location - search given sensor in `sensors` table
|
||||
* @param Nct - controller number
|
||||
* @param Nch - channel number
|
||||
* @param Ns - sensor number
|
||||
* @return
|
||||
* @return pointer to sensor_data for given sensor
|
||||
*/
|
||||
const sensor_data *get_sensor_location(int Nct, int Nch, int Ns){
|
||||
if(Nct < 1 || Nct > NCTRLR_MAX || Nch > NCHANNEL_MAX || Ns > 1){
|
||||
@ -204,6 +204,106 @@ const sensor_data *get_sensor_location(int Nct, int Nch, int Ns){
|
||||
int idx = 2*(NCHANNEL_MAX+1)*(Nct - 1) + 2*Nch + Ns;
|
||||
DBG("Sensor code %d%d%d (idx=%d):\n", Nct, Nch, Ns, idx);
|
||||
const sensor_data *s = sensors + idx;
|
||||
DBG("\tdT=%g; coords=(%d, %d, %d)\n", s->dt, s->X, s->Y, s->Z);
|
||||
DBG("\tdT=%g (adj:%g); coords=(%d, %d, %d)\n", s->dt, s->Tadj, s->X, s->Y, s->Z);
|
||||
return s;
|
||||
}
|
||||
|
||||
// return next non-space character in line until first '\n' or NULL if met '#' or '\n'
|
||||
static char *omitspaces(char *str){
|
||||
char ch;
|
||||
do{
|
||||
ch = *str;
|
||||
if(!ch) return NULL; // EOL
|
||||
if(ch == ' ' || ch == '\t'){
|
||||
++str;
|
||||
continue;
|
||||
}
|
||||
if(ch == '#' || ch == '\n'){
|
||||
return NULL; // comment
|
||||
}
|
||||
return str;
|
||||
}while(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read_adj_file - try to read file with thermal adjustments
|
||||
* @param fname - filename
|
||||
* @return 0 if all OK
|
||||
* thermal adjustments file should have simple structure:
|
||||
* No of sensor (like in output format, e.g. 561) and Tcorr value (Treal = T - Tcorr)
|
||||
* all data after # ignored
|
||||
*/
|
||||
int read_adj_file(char *fname){
|
||||
double Tadj[NSENSORS] = {0,};
|
||||
if(!fname){
|
||||
WARNX("read_adj_file(): filename missing");
|
||||
return 1;
|
||||
}
|
||||
mmapbuf *buf = My_mmap(fname);
|
||||
if(!buf) return 1;
|
||||
char *adjf = buf->data, *eof = adjf + buf->len;
|
||||
DBG("buf: %s", adjf);
|
||||
int strnum = 1; // start string number from 1
|
||||
while(adjf < eof){
|
||||
char *eol = strchr(adjf, '\n');
|
||||
char *nextchar = omitspaces(adjf);
|
||||
if(!nextchar){
|
||||
goto cont;
|
||||
}
|
||||
DBG("First char: %c", *nextchar);
|
||||
char *endptr = NULL;
|
||||
long num = strtol(nextchar, &endptr, 10);
|
||||
if(endptr == nextchar || !endptr){
|
||||
WARNX("Wrong integer number!");
|
||||
goto reperr;
|
||||
}
|
||||
DBG("first num: %ld", num);
|
||||
int Nctrl = num / 100;
|
||||
int Nch = (num - Nctrl*100) / 10;
|
||||
int Nsen = num%10;
|
||||
DBG("Nc=%d, Nch=%d, NS=%d", Nctrl, Nch, Nsen);
|
||||
if(num < 0 || (Nsen != 0 && Nsen != 1) || (Nch < 0 || Nch > NCHANNEL_MAX) || (Nctrl < 1 || Nctrl > NCTRLR_MAX)){
|
||||
WARNX("Wrong sensor number: %ld", num);
|
||||
goto reperr;
|
||||
}
|
||||
int idx = 2*(NCHANNEL_MAX+1)*(Nctrl - 1) + 2*Nch + Nsen;
|
||||
DBG("index: %d", idx);
|
||||
if(idx < 0 || idx > NSENSORS-1){
|
||||
WARNX("Sensor index (%d) over range 0..%d", idx, NSENSORS-1);
|
||||
}
|
||||
nextchar = omitspaces(endptr);
|
||||
if(!nextchar){
|
||||
WARNX("There's no temperature data after sensor's number");
|
||||
goto reperr;
|
||||
}
|
||||
double t = strtod(nextchar, &endptr);
|
||||
if(endptr == nextchar || !endptr){
|
||||
WARNX("Wrong double number!");
|
||||
goto reperr;
|
||||
}
|
||||
DBG("double num: %g", t);
|
||||
Tadj[idx] = t;
|
||||
if(omitspaces(endptr)){
|
||||
WARNX("Wrong file format: each string should include two numbers (and maybe comment after #)");
|
||||
goto reperr;
|
||||
}
|
||||
cont:
|
||||
if(!eol) break;
|
||||
adjf = eol + 1;
|
||||
++strnum;
|
||||
}
|
||||
My_munmap(buf);
|
||||
for(int i = 0; i < NSENSORS; ++i){
|
||||
if(fabs(Tadj[i]) > DBL_EPSILON){
|
||||
printf("Tadj[%d] = %g\n", i, Tadj[i]);
|
||||
}
|
||||
sensors[i].Tadj = Tadj[i];
|
||||
}
|
||||
return 0;
|
||||
reperr:
|
||||
red("Error in string %d:\n", strnum);
|
||||
printf("%s\n", adjf);
|
||||
putlog("Erroneous log file %s in line %d", fname, strnum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -23,14 +23,19 @@
|
||||
#define NCTRLR_MAX (5)
|
||||
// max number of channel
|
||||
#define NCHANNEL_MAX (7)
|
||||
// total amount of sensors @ the mirror
|
||||
#define NSENSORS (NCTRLR_MAX*2*(NCHANNEL_MAX+1))
|
||||
|
||||
typedef struct{
|
||||
float dt;
|
||||
int X;
|
||||
int Y;
|
||||
int Z;
|
||||
float Tadj;
|
||||
} sensor_data;
|
||||
|
||||
const sensor_data *get_sensor_location(int Nct, int Nch, int Ns);
|
||||
|
||||
int read_adj_file(char *fname);
|
||||
|
||||
#endif // SENS_PLACE_H__
|
||||
|
||||
@ -282,10 +282,10 @@ Item quick_select(Item *idata, int n){
|
||||
static void process_T(){
|
||||
int i, N, p, Num = 0;
|
||||
time_t tmeasmax = 0;
|
||||
double arr[128];
|
||||
double arr[NSENSORS];
|
||||
// mean temperatures over 15 scans
|
||||
static double Tmean[2][NCHANNEL_MAX+1][NCTRLR_MAX+1];
|
||||
static int Nmean; // amount of measurements for Tmean
|
||||
static int Nmean[2][NCHANNEL_MAX+1][NCTRLR_MAX+1], Nmeanmax; // amount of measurements for Tmean
|
||||
// get statistics
|
||||
poll_sensors(0); // poll N2
|
||||
// scan over controllers on mirror & calculate median
|
||||
@ -304,32 +304,35 @@ static void process_T(){
|
||||
}
|
||||
// calculate mean
|
||||
double Tmed = quick_select(arr, Num);
|
||||
double Tbot = Tmed - 3., Ttop = Tmed + 3.;
|
||||
double Tbot = Tmed - 10., Ttop = Tmed + 10.;
|
||||
DBG("Got %d values, Tmed=%g", Num, Tmed);
|
||||
// throw out all more than +-3degrC and calculate meanT
|
||||
// throw out all more than +-10degrC and calculate meanT
|
||||
Num = 0;
|
||||
double Tsum = 0.;
|
||||
for(i = 1; i <= NCTRLR_MAX; ++i){
|
||||
for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){
|
||||
double T = t_last[p][N][i];
|
||||
if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > 1800){
|
||||
if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > 1800){ // not longer than 3 minutes ago!
|
||||
t_last[p][N][i] = -300.;
|
||||
Tmean[p][N][i] = -3e9;
|
||||
}else{
|
||||
++Num; Tsum += T;
|
||||
Tmean[p][N][i] += T;
|
||||
++Nmean[p][N][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// make graphics
|
||||
if(G->savepath){
|
||||
if(++Nmean == GRAPHS_AMOUNT){
|
||||
for(i = 1; i <= NCTRLR_MAX; ++i)for(p = 0; p < 2; ++p)for(N = 0; N <= NCHANNEL_MAX; ++ N){
|
||||
Tmean[p][N][i] /= Nmean;
|
||||
if(++Nmeanmax == GRAPHS_AMOUNT){
|
||||
for(i = 1; i <= NCTRLR_MAX; ++i)for(N = 0; N <= NCHANNEL_MAX; ++ N)for(p = 0; p < 2; ++p){
|
||||
if(Nmean[p][N][i]){
|
||||
Tmean[p][N][i] /= Nmean[p][N][i];
|
||||
Nmean[p][N][i] = 0;
|
||||
}else Tmean[p][N][i] = -300.; // no data
|
||||
}
|
||||
plot(Tmean, G->savepath);
|
||||
memset(Tmean, 0, sizeof(double)*2*(NCTRLR_MAX+1)*(NCHANNEL_MAX+1));
|
||||
Nmean = 0;
|
||||
Nmeanmax = 0;
|
||||
}
|
||||
}
|
||||
meanT = Tsum / Num;
|
||||
@ -384,7 +387,7 @@ static void daemon_(int sock){
|
||||
buf = &ptrs[sdata->Z]; len = &lens[sdata->Z];
|
||||
// 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,
|
||||
sdata->X, sdata->Y, T - sdata->dt, tmeasured[p][N][i]);
|
||||
sdata->X, sdata->Y, T - sdata->dt - sdata->Tadj, tmeasured[p][N][i]);
|
||||
}
|
||||
*len -= l;
|
||||
*buf += l;
|
||||
|
||||
6
src/netdaemon/tempadj.txt
Normal file
6
src/netdaemon/tempadj.txt
Normal file
@ -0,0 +1,6 @@
|
||||
#No dT (Treal = T - dT)
|
||||
100 -0.02
|
||||
101 3.
|
||||
# some more comments
|
||||
560 -0.06 # another comment
|
||||
571 -0.01 # test
|
||||
@ -133,7 +133,7 @@ static int parse_answer(char *buf, int N){
|
||||
//DBG("sensor #%d", v);
|
||||
//if(v < 0 || v > 81) return 0;
|
||||
i = v/10; v -= i*10;
|
||||
if(i < 0 || i > NCTRLR_MAX) return 0;
|
||||
if(i < 0 || i > NCHANNEL_MAX) return 0;
|
||||
//DBG("i=%d, v=%d", i,v);
|
||||
if((v & 1) != v) return 0; // should be only 0 or 1
|
||||
if(*buf != '=' ) return 0;
|
||||
@ -144,6 +144,7 @@ static int parse_answer(char *buf, int N){
|
||||
return 0;
|
||||
}
|
||||
t_last[v][i][N] = ((double)T) / 100.;
|
||||
DBG("T(%d_%d%d)=%g", N, i, v, T/100.);
|
||||
tmeasured[v][i][N] = time(NULL);
|
||||
return 1;
|
||||
}
|
||||
@ -196,7 +197,7 @@ int poll_sensors(int N){
|
||||
}
|
||||
int ngot = 0;
|
||||
double t0 = dtime();
|
||||
while(dtime() - t0 < T_POLLING_TMOUT && ngot < 16){ // timeout reached or got data from all
|
||||
while(dtime() - t0 < T_POLLING_TMOUT && ngot < 2*(NCHANNEL_MAX+1)){ // timeout reached or got data from all
|
||||
if((ans = read_string())){ // parse new data
|
||||
//DBG("got %s", ans);
|
||||
if(*ans == CMD_MEASURE_T){ // data from sensor
|
||||
|
||||
@ -204,7 +204,7 @@ mmapbuf *My_mmap(char *filename){
|
||||
void My_munmap(mmapbuf *b){
|
||||
if(munmap(b->data, b->len)){
|
||||
/// "îÅ ÍÏÇÕ munmap"
|
||||
ERR(_("Can't munmap"));
|
||||
WARN(_("Can't munmap"));
|
||||
}
|
||||
FREE(b);
|
||||
}
|
||||
@ -290,12 +290,12 @@ void restore_tty(){
|
||||
#endif
|
||||
// init:
|
||||
void tty_init(char *comdev){
|
||||
DBG("\nOpen port %s ...\n", comdev);
|
||||
DBG("\nOpen port %s ...", comdev);
|
||||
do{
|
||||
comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK);
|
||||
}while (comfd == -1 && errno == EINTR);
|
||||
if(comfd < 0){
|
||||
WARN("Can't use port %s\n",comdev);
|
||||
WARN("Can't use port %s",comdev);
|
||||
signals(-1); // quit?
|
||||
}
|
||||
// make exclusive open
|
||||
@ -321,7 +321,7 @@ void tty_init(char *comdev){
|
||||
WARN(_("Can't set settings"));
|
||||
signals(-1);
|
||||
}
|
||||
DBG(" OK\n");
|
||||
DBG(" OK");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user