mirror of
https://github.com/eddyem/tsys01.git
synced 2026-02-01 12:55:08 +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
|
// default values for Gdefault & help
|
||||||
#define DEFAULT_COMDEV "/dev/ttyUSB0"
|
#define DEFAULT_COMDEV "/dev/ttyUSB0"
|
||||||
#define DEFAULT_PORT "4444"
|
#define DEFAULT_PORT "4444"
|
||||||
|
#define DEFAULT_PIDFILE "/tmp/TSYS01daemon.pid"
|
||||||
|
|
||||||
// DEFAULTS
|
// DEFAULTS
|
||||||
// default global parameters
|
// default global parameters
|
||||||
@ -45,7 +46,9 @@ glob_pars const Gdefault = {
|
|||||||
.savepath = NULL,
|
.savepath = NULL,
|
||||||
.makegraphs = 0,
|
.makegraphs = 0,
|
||||||
.rest_pars = NULL,
|
.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")},
|
{"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)")},
|
{"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")},
|
{"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
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,9 @@ typedef struct{
|
|||||||
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)
|
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;
|
} 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);
|
const sensor_data *sdata = get_sensor_location(i, N, p);
|
||||||
if(!sdata) continue;
|
if(!sdata) continue;
|
||||||
if(Z != sdata->Z) 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,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
#include "usefull_macros.h"
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/wait.h> // wait
|
#include <sys/wait.h> // wait
|
||||||
#include <sys/prctl.h> //prctl
|
#include <sys/prctl.h> //prctl
|
||||||
|
#include "checkfile.h"
|
||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
#include "socket.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){
|
void signals(int signo){
|
||||||
restore_console();
|
restore_console();
|
||||||
restore_tty();
|
restore_tty();
|
||||||
@ -34,35 +37,64 @@ void signals(int signo){
|
|||||||
exit(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){
|
int main(int argc, char **argv){
|
||||||
initial_setup();
|
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);
|
G = parse_args(argc, argv);
|
||||||
if(G->rest_pars_num)
|
if(G->rest_pars_num)
|
||||||
openlogfile(G->rest_pars[0]);
|
openlogfile(G->rest_pars[0]);
|
||||||
if(G->makegraphs && !G->savepath){
|
if(G->makegraphs && !G->savepath){
|
||||||
ERRX(_("Point the path to graphical files"));
|
ERRX(_("Point the path to graphical files"));
|
||||||
}
|
}
|
||||||
#ifndef EBUG
|
DBG("t=%d", G->testadjfile);
|
||||||
if(daemon(1, 0)){
|
int raf = read_adj_file(G->adjfilename);
|
||||||
ERR("daemon()");
|
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
|
if(runningproc) ERRX("Found running process, pid=%d.", runningproc);
|
||||||
pid_t childpid = fork();
|
signal(SIGTERM, signals); // kill (-15) - quit
|
||||||
if(childpid){
|
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||||
putlog("create child with PID %d\n", childpid);
|
signal(SIGINT, signals); // ctrl+C - quit
|
||||||
DBG("Created child with PID %d\n", childpid);
|
signal(SIGQUIT, signals); // ctrl+\ - quit
|
||||||
wait(NULL);
|
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
|
||||||
putlog("child %d died\n", childpid);
|
signal(SIGUSR1, refreshAdj); // refresh adjustements
|
||||||
WARNX("Child %d died\n", childpid);
|
#ifndef EBUG
|
||||||
sleep(1);
|
if(!G->terminal){
|
||||||
}else{
|
if(daemon(1, 0)){
|
||||||
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
ERR("daemon()");
|
||||||
break; // go out to normal functional
|
}
|
||||||
|
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
|
#endif
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include "sens_place.h"
|
#include "sens_place.h"
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
#include "math.h" // fabs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sensor place Dt X Y Z
|
Sensor place Dt X Y Z
|
||||||
@ -104,97 +105,96 @@
|
|||||||
571 18 0.02 13 3 0
|
571 18 0.02 13 3 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const sensor_data sensors[] = {
|
static sensor_data sensors[NSENSORS] = {
|
||||||
// {Dt,X,Y,Z},
|
// {Dt,X,Y,Z},
|
||||||
{-0.07, 19, 7, 0}, // 0
|
{-0.07, 19, 7, 0, 0}, // 0
|
||||||
{0.03, 20, 0, 0}, // 1
|
{0.03, 20, 0, 0, 0}, // 1
|
||||||
{0.03, 19, -7, 0}, // 2
|
{0.03, 19, -7, 0, 0}, // 2
|
||||||
{-0.05, 17, -10, 1}, // 3
|
{-0.05, 17, -10, 1, 0}, // 3
|
||||||
{0.02, 17, -22, 0}, // 4
|
{0.02, 17, -22, 0, 0}, // 4
|
||||||
{-0.03, 15, -13, 0}, // 5
|
{-0.03, 15, -13, 0, 0}, // 5
|
||||||
{0.02, 22, -17, 0}, // 6
|
{0.02, 22, -17, 0, 0}, // 6
|
||||||
{-0.09, 24, -14, 1}, // 7
|
{-0.09, 24, -14, 1, 0}, // 7
|
||||||
{0.03, 25, -10, 0}, // 8
|
{0.03, 25, -10, 0, 0}, // 8
|
||||||
{0.02, 27, -4, 0}, // 9
|
{0.02, 27, -4, 0, 0}, // 9
|
||||||
{-0.01, 27, 4, 0}, // 10
|
{-0.01, 27, 4, 0, 0}, // 10
|
||||||
{-0.09, 25, 10, 0}, // 11
|
{-0.09, 25, 10, 0, 0}, // 11
|
||||||
{0.07, 22, 17, 0}, // 12
|
{0.07, 22, 17, 0, 0}, // 12
|
||||||
{0, 24, 14, 1}, // 13
|
{0, 24, 14, 1, 0}, // 13
|
||||||
{0.02, 10, 25, 0}, // 14
|
{0.02, 10, 25, 0, 0}, // 14
|
||||||
{0.08, 17, 22, 0}, // 15
|
{0.08, 17, 22, 0, 0}, // 15
|
||||||
{-0.01, 4, 27, 0}, // 16
|
{-0.01, 4, 27, 0, 0}, // 16
|
||||||
{-0.03, 0, 27, 1}, // 17
|
{-0.03, 0, 27, 1, 0}, // 17
|
||||||
{0.04, -4, 27, 0}, // 18
|
{0.04, -4, 27, 0, 0}, // 18
|
||||||
{-0.01, -10, 25, 0}, // 19
|
{-0.01, -10, 25, 0, 0}, // 19
|
||||||
{-0.02, -17, 22, 0}, // 20
|
{-0.02, -17, 22, 0, 0}, // 20
|
||||||
{-0.04, -22, 17, 0}, // 21
|
{-0.04, -22, 17, 0, 0}, // 21
|
||||||
{0.03, -25, 10, 0}, // 22
|
{0.03, -25, 10, 0, 0}, // 22
|
||||||
{-0.03, -24, 14, 1}, // 23
|
{-0.03, -24, 14, 1, 0}, // 23
|
||||||
{-0.03, -27, -4, 0}, // 24
|
{-0.03, -27, -4, 0, 0}, // 24
|
||||||
{0.03, -27, 4, 0}, // 25
|
{0.03, -27, 4, 0, 0}, // 25
|
||||||
{-0.05, -25, -10, 0}, // 26
|
{-0.05, -25, -10, 0, 0}, // 26
|
||||||
{0, -24, -14, 1}, // 27
|
{0, -24, -14, 1, 0}, // 27
|
||||||
{0.03, -22, -17, 0}, // 28
|
{0.03, -22, -17, 0, 0}, // 28
|
||||||
{-0.05, -17, -22, 0}, // 29
|
{-0.05, -17, -22, 0, 0}, // 29
|
||||||
{-0.02, -10, -25, 0}, // 30
|
{-0.02, -10, -25, 0, 0}, // 30
|
||||||
{0.04, -4, -27, 0}, // 31
|
{0.04, -4, -27, 0, 0}, // 31
|
||||||
{0.12, -3, -20, 0}, // 32
|
{0.12, -3, -20, 0, 0}, // 32
|
||||||
{0, -10, -17, 0}, // 33
|
{0, -10, -17, 0, 0}, // 33
|
||||||
{-0.08, -15, -13, 0}, // 34
|
{-0.08, -15, -13, 0, 0}, // 34
|
||||||
{-0.08, -17, -10, 1}, // 35
|
{-0.08, -17, -10, 1, 0}, // 35
|
||||||
{-0.1, -19, -7, 0}, // 36
|
{-0.1, -19, -7, 0, 0}, // 36
|
||||||
{-0.04, -20, 0, 0}, // 37
|
{-0.04, -20, 0, 0, 0}, // 37
|
||||||
{-0.08, -19, 7, 0}, // 38
|
{-0.08, -19, 7, 0, 0}, // 38
|
||||||
{0.03, -17, 10, 1}, // 39
|
{0.03, -17, 10, 1, 0}, // 39
|
||||||
{0.11, -15, 13, 0}, // 40
|
{0.11, -15, 13, 0, 0}, // 40
|
||||||
{0.07, -10, 17, 0}, // 41
|
{0.07, -10, 17, 0, 0}, // 41
|
||||||
{0.09, -3, 20, 0}, // 42
|
{0.09, -3, 20, 0, 0}, // 42
|
||||||
{-0.09, 0, 20, 1}, // 43
|
{-0.09, 0, 20, 1, 0}, // 43
|
||||||
{-0.1, 3, 20, 0}, // 44
|
{-0.1, 3, 20, 0, 0}, // 44
|
||||||
{0.04, 10, 17, 0}, // 45
|
{0.04, 10, 17, 0, 0}, // 45
|
||||||
{0.05, 15, 13, 0}, // 46
|
{0.05, 15, 13, 0, 0}, // 46
|
||||||
{-0.04, 17, 10, 1}, // 47
|
{-0.04, 17, 10, 1, 0}, // 47
|
||||||
{0.01, 9, 9, 0}, // 48
|
{0.01, 9, 9, 0, 0}, // 48
|
||||||
{-0.04, 11, 7, 1}, // 49
|
{-0.04, 11, 7, 1, 0}, // 49
|
||||||
{0.01, 3, 13, 0}, // 50
|
{0.01, 3, 13, 0, 0}, // 50
|
||||||
{-0.04, 0, 13, 1}, // 51
|
{-0.04, 0, 13, 1, 0}, // 51
|
||||||
{0.14, -9, 9, 0}, // 52
|
{0.14, -9, 9, 0, 0}, // 52
|
||||||
{0, -3, 13, 0}, // 53
|
{0, -3, 13, 0, 0}, // 53
|
||||||
{0.07, -13, 3, 0}, // 54
|
{0.07, -13, 3, 0, 0}, // 54
|
||||||
{-0.02, -11, 7, 1}, // 55
|
{-0.02, -11, 7, 1, 0}, // 55
|
||||||
{0.04, -13, -3, 0}, // 56
|
{0.04, -13, -3, 0, 0}, // 56
|
||||||
{-0.06, -11, -7, 1}, // 57
|
{-0.06, -11, -7, 1, 0}, // 57
|
||||||
{0.01, -9, -9, 0}, // 58
|
{0.01, -9, -9, 0, 0}, // 58
|
||||||
{0.08, -3, -13, 0}, // 59
|
{0.08, -3, -13, 0, 0}, // 59
|
||||||
{-0.09, 3, -13, 0}, // 60
|
{-0.09, 3, -13, 0, 0}, // 60
|
||||||
{-0.04, 0, -13, 1}, // 61
|
{-0.04, 0, -13, 1, 0}, // 61
|
||||||
{0.06, 3, -20, 0}, // 62
|
{0.06, 3, -20, 0, 0}, // 62
|
||||||
{-0.05, 0, -20, 1}, // 63
|
{-0.05, 0, -20, 1, 0}, // 63
|
||||||
{0.05, 4, -27, 0}, // 64
|
{0.05, 4, -27, 0, 0}, // 64
|
||||||
{-0.08, 0, -27, 1}, // 65
|
{-0.08, 0, -27, 1, 0}, // 65
|
||||||
{0.1, 10, -17, 0}, // 66
|
{0.1, 10, -17, 0, 0}, // 66
|
||||||
{-0.05, 10, -25, 0}, // 67
|
{-0.05, 10, -25, 0, 0}, // 67
|
||||||
{0, 9, -9, 0}, // 68
|
{0, 9, -9, 0, 0}, // 68
|
||||||
{0.01, 11, -7, 1}, // 69
|
{0.01, 11, -7, 1, 0}, // 69
|
||||||
{0, 3, -5, 0}, // 70
|
{0, 3, -5, 0, 0}, // 70
|
||||||
{-0.02, 0, -6, 1}, // 71
|
{-0.02, 0, -6, 1, 0}, // 71
|
||||||
{0.05, -3, -5, 0}, // 72
|
{0.05, -3, -5, 0, 0}, // 72
|
||||||
{-0.03, -6, 0, 0}, // 73
|
{-0.03, -6, 0, 0, 0}, // 73
|
||||||
{0.03, -3, 5, 0}, // 74
|
{0.03, -3, 5, 0, 0}, // 74
|
||||||
{0.06, 0, 6, 1}, // 75
|
{0.06, 0, 6, 1, 0}, // 75
|
||||||
{0, 3, 5, 0}, // 76
|
{0, 3, 5, 0, 0}, // 76
|
||||||
{-0.06, 6, 0, 0}, // 77
|
{-0.06, 6, 0, 0, 0}, // 77
|
||||||
{-0.07, 13, -3, 0}, // 78
|
{-0.07, 13, -3, 0, 0}, // 78
|
||||||
{0.02, 13, 3, 0}, // 79
|
{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 Nct - controller number
|
||||||
* @param Nch - channel number
|
* @param Nch - channel number
|
||||||
* @param Ns - sensor 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){
|
const sensor_data *get_sensor_location(int Nct, int Nch, int Ns){
|
||||||
if(Nct < 1 || Nct > NCTRLR_MAX || Nch > NCHANNEL_MAX || Ns > 1){
|
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;
|
int idx = 2*(NCHANNEL_MAX+1)*(Nct - 1) + 2*Nch + Ns;
|
||||||
DBG("Sensor code %d%d%d (idx=%d):\n", Nct, Nch, Ns, idx);
|
DBG("Sensor code %d%d%d (idx=%d):\n", Nct, Nch, Ns, idx);
|
||||||
const sensor_data *s = sensors + 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 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)
|
#define NCTRLR_MAX (5)
|
||||||
// max number of channel
|
// max number of channel
|
||||||
#define NCHANNEL_MAX (7)
|
#define NCHANNEL_MAX (7)
|
||||||
|
// total amount of sensors @ the mirror
|
||||||
|
#define NSENSORS (NCTRLR_MAX*2*(NCHANNEL_MAX+1))
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
float dt;
|
float dt;
|
||||||
int X;
|
int X;
|
||||||
int Y;
|
int Y;
|
||||||
int Z;
|
int Z;
|
||||||
|
float Tadj;
|
||||||
} sensor_data;
|
} sensor_data;
|
||||||
|
|
||||||
const sensor_data *get_sensor_location(int Nct, int Nch, int Ns);
|
const sensor_data *get_sensor_location(int Nct, int Nch, int Ns);
|
||||||
|
|
||||||
|
int read_adj_file(char *fname);
|
||||||
|
|
||||||
#endif // SENS_PLACE_H__
|
#endif // SENS_PLACE_H__
|
||||||
|
|||||||
@ -282,10 +282,10 @@ Item quick_select(Item *idata, int n){
|
|||||||
static void process_T(){
|
static void process_T(){
|
||||||
int i, N, p, Num = 0;
|
int i, N, p, Num = 0;
|
||||||
time_t tmeasmax = 0;
|
time_t tmeasmax = 0;
|
||||||
double arr[128];
|
double arr[NSENSORS];
|
||||||
// mean temperatures over 15 scans
|
// mean temperatures over 15 scans
|
||||||
static double Tmean[2][NCHANNEL_MAX+1][NCTRLR_MAX+1];
|
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
|
// get statistics
|
||||||
poll_sensors(0); // poll N2
|
poll_sensors(0); // poll N2
|
||||||
// scan over controllers on mirror & calculate median
|
// scan over controllers on mirror & calculate median
|
||||||
@ -304,32 +304,35 @@ static void process_T(){
|
|||||||
}
|
}
|
||||||
// calculate mean
|
// calculate mean
|
||||||
double Tmed = quick_select(arr, Num);
|
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);
|
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;
|
Num = 0;
|
||||||
double Tsum = 0.;
|
double Tsum = 0.;
|
||||||
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){
|
if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > 1800){ // not longer than 3 minutes ago!
|
||||||
t_last[p][N][i] = -300.;
|
t_last[p][N][i] = -300.;
|
||||||
Tmean[p][N][i] = -3e9;
|
|
||||||
}else{
|
}else{
|
||||||
++Num; Tsum += T;
|
++Num; Tsum += T;
|
||||||
Tmean[p][N][i] += T;
|
Tmean[p][N][i] += T;
|
||||||
|
++Nmean[p][N][i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// make graphics
|
// make graphics
|
||||||
if(G->savepath){
|
if(G->savepath){
|
||||||
if(++Nmean == GRAPHS_AMOUNT){
|
if(++Nmeanmax == GRAPHS_AMOUNT){
|
||||||
for(i = 1; i <= NCTRLR_MAX; ++i)for(p = 0; p < 2; ++p)for(N = 0; N <= NCHANNEL_MAX; ++ N){
|
for(i = 1; i <= NCTRLR_MAX; ++i)for(N = 0; N <= NCHANNEL_MAX; ++ N)for(p = 0; p < 2; ++p){
|
||||||
Tmean[p][N][i] /= Nmean;
|
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);
|
plot(Tmean, G->savepath);
|
||||||
memset(Tmean, 0, sizeof(double)*2*(NCTRLR_MAX+1)*(NCHANNEL_MAX+1));
|
memset(Tmean, 0, sizeof(double)*2*(NCTRLR_MAX+1)*(NCHANNEL_MAX+1));
|
||||||
Nmean = 0;
|
Nmeanmax = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
meanT = Tsum / Num;
|
meanT = Tsum / Num;
|
||||||
@ -384,7 +387,7 @@ static void daemon_(int sock){
|
|||||||
buf = &ptrs[sdata->Z]; len = &lens[sdata->Z];
|
buf = &ptrs[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, tmeasured[p][N][i]);
|
sdata->X, sdata->Y, T - sdata->dt - sdata->Tadj, tmeasured[p][N][i]);
|
||||||
}
|
}
|
||||||
*len -= l;
|
*len -= l;
|
||||||
*buf += 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);
|
//DBG("sensor #%d", v);
|
||||||
//if(v < 0 || v > 81) return 0;
|
//if(v < 0 || v > 81) return 0;
|
||||||
i = v/10; v -= i*10;
|
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);
|
//DBG("i=%d, v=%d", i,v);
|
||||||
if((v & 1) != v) return 0; // should be only 0 or 1
|
if((v & 1) != v) return 0; // should be only 0 or 1
|
||||||
if(*buf != '=' ) return 0;
|
if(*buf != '=' ) return 0;
|
||||||
@ -144,6 +144,7 @@ static int parse_answer(char *buf, int N){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
t_last[v][i][N] = ((double)T) / 100.;
|
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);
|
tmeasured[v][i][N] = time(NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -196,7 +197,7 @@ int poll_sensors(int N){
|
|||||||
}
|
}
|
||||||
int ngot = 0;
|
int ngot = 0;
|
||||||
double t0 = dtime();
|
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
|
if((ans = read_string())){ // parse new data
|
||||||
//DBG("got %s", ans);
|
//DBG("got %s", ans);
|
||||||
if(*ans == CMD_MEASURE_T){ // data from sensor
|
if(*ans == CMD_MEASURE_T){ // data from sensor
|
||||||
|
|||||||
@ -204,7 +204,7 @@ mmapbuf *My_mmap(char *filename){
|
|||||||
void My_munmap(mmapbuf *b){
|
void My_munmap(mmapbuf *b){
|
||||||
if(munmap(b->data, b->len)){
|
if(munmap(b->data, b->len)){
|
||||||
/// "îÅ ÍÏÇÕ munmap"
|
/// "îÅ ÍÏÇÕ munmap"
|
||||||
ERR(_("Can't munmap"));
|
WARN(_("Can't munmap"));
|
||||||
}
|
}
|
||||||
FREE(b);
|
FREE(b);
|
||||||
}
|
}
|
||||||
@ -290,12 +290,12 @@ void restore_tty(){
|
|||||||
#endif
|
#endif
|
||||||
// init:
|
// init:
|
||||||
void tty_init(char *comdev){
|
void tty_init(char *comdev){
|
||||||
DBG("\nOpen port %s ...\n", comdev);
|
DBG("\nOpen port %s ...", comdev);
|
||||||
do{
|
do{
|
||||||
comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK);
|
comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK);
|
||||||
}while (comfd == -1 && errno == EINTR);
|
}while (comfd == -1 && errno == EINTR);
|
||||||
if(comfd < 0){
|
if(comfd < 0){
|
||||||
WARN("Can't use port %s\n",comdev);
|
WARN("Can't use port %s",comdev);
|
||||||
signals(-1); // quit?
|
signals(-1); // quit?
|
||||||
}
|
}
|
||||||
// make exclusive open
|
// make exclusive open
|
||||||
@ -321,7 +321,7 @@ void tty_init(char *comdev){
|
|||||||
WARN(_("Can't set settings"));
|
WARN(_("Can't set settings"));
|
||||||
signals(-1);
|
signals(-1);
|
||||||
}
|
}
|
||||||
DBG(" OK\n");
|
DBG(" OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user