diff --git a/src/netdaemon/Readme.md b/src/netdaemon/Readme.md index 78288eb..bff20f8 100644 --- a/src/netdaemon/Readme.md +++ b/src/netdaemon/Readme.md @@ -4,6 +4,7 @@ BTA mirror temperature network daemon Gather information from temperature sensors and send it over ethernet by network request like hostname:4444/Tx where x is 0 for upper sensors, 1 for lower and 2 for T measured by main controller. +hostname:4444/Tmean returns mean temperature Answer format: "X Y T t", where diff --git a/src/netdaemon/netdaemon.c.tags b/src/netdaemon/netdaemon.c.tags index dba5009..093cdc6 100644 --- a/src/netdaemon/netdaemon.c.tags +++ b/src/netdaemon/netdaemon.c.tags @@ -346,6 +346,8 @@ EL2HLT EL2NSYNCÌ65536Ö0 EL3HLTÌ65536Ö0 EL3RSTÌ65536Ö0 +ELEM_SWAPÌ65536Ö0 +ELEM_SWAPÌ131072Í(a,b)Ö0 ELIBACCÌ65536Ö0 ELIBBADÌ65536Ö0 ELIBEXECÌ65536Ö0 @@ -836,6 +838,7 @@ IUTF8 IXANYÌ65536Ö0 IXOFFÌ65536Ö0 IXONÌ65536Ö0 +ItemÌ4096Ö0Ïdouble LC_ADDRESSÌ65536Ö0 LC_ADDRESS_MASKÌ65536Ö0 LC_ALLÌ65536Ö0 @@ -1236,6 +1239,8 @@ PF_VSOCK PF_WANPIPEÌ65536Ö0 PF_X25Ì65536Ö0 PIPE_BUFÌ65536Ö0 +PIX_SORTÌ65536Ö0 +PIX_SORTÌ131072Í(a,b)Ö0 PKEY_DISABLE_ACCESSÌ65536Ö0 PKEY_DISABLE_WRITEÌ65536Ö0 POLLING_TMOUTÌ65536Ö0 @@ -4540,8 +4545,8 @@ __kernel_caddr_t __kernel_clock_tÌ4096Ö0Ï__kernel_long_t __kernel_clockid_tÌ4096Ö0Ïint __kernel_daddr_tÌ4096Ö0Ïint -__kernel_fd_setÌ4096Ö0Ïanon_struct_8 -__kernel_fsid_tÌ4096Ö0Ïanon_struct_9 +__kernel_fd_setÌ4096Ö0Ïanon_struct_21 +__kernel_fsid_tÌ4096Ö0Ïanon_struct_22 __kernel_gid16_tÌ4096Ö0Ïunsigned short __kernel_gid32_tÌ4096Ö0Ïunsigned int __kernel_gid_tÌ4096Ö0Ïunsigned int @@ -4618,6 +4623,7 @@ __sigevent_t_defined __siginfo_t_definedÌ65536Ö0 __sigset_t_definedÌ65536Ö0 __sigstack_definedÌ65536Ö0 +__sigval_tÌ4096Ö0Ïsigval __sigval_t_definedÌ65536Ö0 __size_tÌ65536Ö0 __size_t__Ì65536Ö0 @@ -4689,7 +4695,13 @@ __wsum __wurÌ65536Ö0 __x86_64Ì65536Ö0 __x86_64__Ì65536Ö0 +_attributeÌ64Îsigevent::anon_union_8::anon_struct_9Ö0Ïpthread_attr_t * +_functionÌ1024Í(__sigval_t)Îsigevent::anon_union_8::anon_struct_9Ö0Ïvoid +_padÌ64Îsigevent::anon_union_8Ö0Ïint _pthread_cleanup_bufferÌ2048Ö0 +_sigev_threadÌ64Îsigevent::anon_union_8Ö0Ïanon_struct_9 +_sigev_unÌ64ÎsigeventÖ0Ïanon_union_8 +_tidÌ64Îsigevent::anon_union_8Ö0Ï__pid_t abortÌ64ÎstdÖ0Ïusing abortÌ65536Ö0 absÌ64ÎstdÖ0Ïusing @@ -4718,11 +4730,13 @@ anon_enum_6 anon_struct_0Ì2048Ö0 anon_struct_1Ì2048Ö0 anon_struct_10Ì2048Ö0 +anon_struct_21Ì2048Ö0 +anon_struct_22Ì2048Ö0 anon_struct_4Ì2048Ö0 anon_struct_5Ì2048Ö0 anon_struct_7Ì2048Ö0 -anon_struct_8Ì2048Ö0 -anon_struct_9Ì2048Ö0 +anon_struct_9Ì2048Îsigevent::anon_union_8Ö0 +anon_union_8Ì8192ÎsigeventÖ0 arg_doubleÌ4Îanon_enum_2Ö0 arg_endÌ64Îprctl_mm_mapÖ0Ï__u64 arg_floatÌ4Îanon_enum_2Ö0 @@ -4851,7 +4865,7 @@ fdim fdimÌ65536Ö0 fdimfÌ65536Ö0 fdimlÌ65536Ö0 -fds_bitsÌ64Îanon_struct_8Ö0Ïunsigned long +fds_bitsÌ64Îanon_struct_21Ö0Ïunsigned long flagÌ64Îanon_struct_4Ö0Ïint * floorÌ64ÎstdÖ0Ïusing floorÌ65536Ö0 @@ -5028,6 +5042,7 @@ mbstowcs mbstowcsÌ65536Ö0 mbtowcÌ64ÎstdÖ0Ïusing mbtowcÌ65536Ö0 +meanTÌ16384Ö0Ïdouble minÌ65536Ö0 mmapbufÌ4096Ö0Ïanon_struct_1 mode_tÌ4096Ö0Ï__mode_t @@ -5090,6 +5105,7 @@ pow ppsfreqÌ64ÎtimexÖ0Ï__syscall_slong_t prctl_mm_mapÌ2048Ö0 precisionÌ64ÎtimexÖ0Ï__syscall_slong_t +process_TÌ16Í()Ö0Ïvoid pthread_cleanup_popÌ131072Í(execute)Ö0 pthread_cleanup_pop_restore_npÌ131072Í(execute)Ö0 pthread_cleanup_pushÌ131072Í(routine,arg)Ö0 @@ -5101,6 +5117,7 @@ qsort qsortÌ65536Ö0 quick_exitÌ64ÎstdÖ0Ïusing quick_exitÌ65536Ö0 +quick_selectÌ16Í(Item *idata, int n)Ö0ÏItem r_WARNÌ16Í(const char *fmt, ...)Ö0Ïint r_pr_Ì16Í(const char *fmt, ...)Ö0Ïint r_pr_nottyÌ16Í(const char *fmt, ...)Ö0Ïint @@ -5184,19 +5201,27 @@ si_uid si_upperÌ65536Ö0 si_utimeÌ65536Ö0 si_valueÌ65536Ö0 +sigev_notifyÌ64ÎsigeventÖ0Ïint sigev_notify_attributesÌ65536Ö0 sigev_notify_functionÌ65536Ö0 +sigev_signoÌ64ÎsigeventÖ0Ïint +sigev_valueÌ64ÎsigeventÖ0Ï__sigval_t +sigeventÌ2048Ö0 sigeventÌ32768Ö0 +sigevent_tÌ4096Ö0Ïsigevent sigmaskÌ131072Í(sig)Ö0 signalsÌ16Í(int signo)Ö0Ïvoid signalsÌ1024Í(int sig)Ö0Ïvoid signbitÌ64ÎstdÖ0Ïusing signbitÌ65536Ö0 signbitÌ131072Í(x)Ö0 +sigvalÌ8192Ö0 sinÌ64ÎstdÖ0Ïusing sinÌ65536Ö0 sinhÌ64ÎstdÖ0Ïusing sinhÌ65536Ö0 +sival_intÌ64ÎsigvalÖ0Ïint +sival_ptrÌ64ÎsigvalÖ0Ïvoid * sqrtÌ64ÎstdÖ0Ïusing sqrtÌ65536Ö0 srandÌ64ÎstdÖ0Ïusing @@ -5304,8 +5329,8 @@ va_arg va_copyÌ131072Í(d,s)Ö0 va_endÌ131072Í(v)Ö0 va_startÌ131072Í(v,l)Ö0 +valÌ64Îanon_struct_22Ö0Ïint valÌ64Îanon_struct_4Ö0Ïint -valÌ64Îanon_struct_9Ö0Ïint waittoreadÌ16Í(int sock)Ö0Ïint wcstombsÌ64ÎstdÖ0Ïusing wcstombsÌ65536Ö0 diff --git a/src/netdaemon/netdaemon.geany b/src/netdaemon/netdaemon.geany index d5f80fe..0537420 100644 --- a/src/netdaemon/netdaemon.geany +++ b/src/netdaemon/netdaemon.geany @@ -20,13 +20,24 @@ indent_mode=3 [project] name=netdaemon base_path=/home/eddy/Docs/SAO/BTA/MIRROR_CONTROL_termo/Project/netdaemon +description= [long line marker] long_line_behaviour=1 long_line_column=100 [files] -current_page=-1 +current_page=3 +FILE_NAME_0=0;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fcmdlnopts.c;0;4 +FILE_NAME_1=0;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fcmdlnopts.h;0;4 +FILE_NAME_2=0;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fmain.c;0;4 +FILE_NAME_3=9982;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fsocket.c;0;4 +FILE_NAME_4=0;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fsocket.h;0;4 +FILE_NAME_5=4650;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fterm.c;0;4 +FILE_NAME_6=0;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fterm.h;0;4 +FILE_NAME_7=3250;C;0;EKOI8-R;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FBTA%2FMIRROR_CONTROL_termo%2FProject%2Fnetdaemon%2Fdatapoints.xy;0;4 +FILE_NAME_8=7594;C;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDropbox%2FProjects%2Ffits_filter%2Fmedian.c;0;4 +FILE_NAME_9=0;C;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDropbox%2FProjects%2Ffits_filter%2Fmedian.h;0;4 [VTE] last_dir=/home/eddy diff --git a/src/netdaemon/socket.c b/src/netdaemon/socket.c index 5033f03..c65c872 100644 --- a/src/netdaemon/socket.c +++ b/src/netdaemon/socket.c @@ -39,6 +39,8 @@ // temperatures: T0, T1, N2 static char strT[3][BUFLEN]; +// mean temperature +static double meanT; /**************** COMMON FUNCTIONS ****************/ /** @@ -171,8 +173,13 @@ static void *handle_socket(void *asock){ putlog("can't send data, some error occured"); } pthread_mutex_unlock(&mutex); - break; - }else break; // here can be more parsers + }else if(strncmp("Tmean", found, 5) == 0){ // send user meanT + char tbuf[10]; + ssize_t L = snprintf(tbuf, 10, "%.2f", meanT); + if(L != write(sock, tbuf, L)) WARN("write()"); + //DBG("Ask Tmean = %g", meanT); + } // here can be more parsers + break; } close(sock); //DBG("closed"); @@ -219,7 +226,98 @@ static void *server(void *asock){ putlog("server(): UNREACHABLE CODE REACHED!"); } -// data gathering & socket parsing +typedef double Item; +#define ELEM_SWAP(a, b) {register Item t = a; a = b; b = t;} +#define PIX_SORT(a, b) {if (a > b) ELEM_SWAP(a, b);} +/** + * quick select - algo for approximate median calculation for array idata of size n + */ +Item quick_select(Item *idata, int n){ + int low, high; + int median; + int middle, ll, hh; + Item *arr = MALLOC(Item, n); + memcpy(arr, idata, n*sizeof(Item)); + low = 0 ; high = n-1 ; median = (low + high) / 2; + for(;;){ + if(high <= low) // One element only + break; + if(high == low + 1){ // Two elements only + PIX_SORT(arr[low], arr[high]) ; + break; + } + // Find median of low, middle and high items; swap into position low + middle = (low + high) / 2; + PIX_SORT(arr[middle], arr[high]) ; + PIX_SORT(arr[low], arr[high]) ; + PIX_SORT(arr[middle], arr[low]) ; + // Swap low item (now in position middle) into position (low+1) + ELEM_SWAP(arr[middle], arr[low+1]) ; + // Nibble from each end towards middle, swapping items when stuck + ll = low + 1; + hh = high; + for(;;){ + do ll++; while (arr[low] > arr[ll]); + do hh--; while (arr[hh] > arr[low]); + if(hh < ll) break; + ELEM_SWAP(arr[ll], arr[hh]) ; + } + // Swap middle item (in position low) back into correct position + ELEM_SWAP(arr[low], arr[hh]) ; + // Re-set active partition + if (hh <= median) low = ll; + if (hh >= median) high = hh - 1; + } + Item ret = arr[median]; + FREE(arr); + return ret; +} +#undef PIX_SORT +#undef ELEM_SWAP + +static void process_T(){ + int i, Num = 0; + time_t tmeasmax = 0; + double arr[128]; + // get statistics + poll_sensors(0); // poll N2 + // scan over controllers on mirror & calculate median + for(i = 1; i < 8; ++i){ + if(poll_sensors(i)){ + int N, p; + for(p = 0; p < 2; ++p) for(N = 0; N < 8; ++ N){ + double T = t_last[p][N][i]; + time_t t = tmeasured[p][N][i]; + if(T > -100. && T < 100.){ + arr[Num++] = T; + if(t > tmeasmax) tmeasmax = t; + } + } + } + } + // calculate mean + double Tmed = quick_select(arr, Num); + double Tbot = Tmed - 3., Ttop = Tmed + 3.; + DBG("Got %d values, Tmed=%g", Num, Tmed); + // throw out all more than +-3degrC and calculate meanT + Num = 0; + double Tsum = 0.; + for(i = 1; i < 8; ++i){ + int N, p; + for(p = 0; p < 2; ++p) for(N = 0; N < 8; ++ N){ + double T = t_last[p][N][i]; + if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > 1800){ + t_last[p][N][i] = -300.; + }else{ + ++Num; Tsum += T; + } + } + } + meanT = Tsum / Num; + DBG("got %d, mean: %g\n\n", Num, meanT); +} + +// data gathering & socket management static void daemon_(int sock){ if(sock < 0) return; pthread_t sock_thread; @@ -245,34 +343,33 @@ static void daemon_(int sock){ char bufs[3][BUFLEN]; // temporary buffers char *ptrs[3] = {bufs[0], bufs[1], bufs[2]}; size_t lens[3] = {BUFLEN, BUFLEN, BUFLEN}; // free space + process_T(); // get new temperatures & throw out bad results for(i = 0; i < 8; ++i){ // scan over controllers - if(poll_sensors(i)){ - int N, p; - for(p = 0; p < 2; ++p) for(N = 0; N < 8; ++ N){ - double T = t_last[p][N][i]; - char **buf; - size_t *len; - //DBG("T%d [%d][%d] = %g",i, p,N,T); - if(T > -100. && T < 100.){ // fill buffer - size_t l; - if(i == 0){ - buf = &ptrs[2]; len = &lens[2]; - // Nsens Npair T time - l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", N, p, T, - tmeasured[p][N][i]); - }else{ - buf = &ptrs[p]; len = &lens[p]; - // x y T time - l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", SensCoords[N][i][0], - SensCoords[N][i][1], T, tmeasured[p][N][i]); - } - *len -= l; - *buf += l; + int N, p; + for(p = 0; p < 2; ++p) for(N = 0; N < 8; ++ N){ + double T = t_last[p][N][i]; + char **buf; + size_t *len; + //DBG("T%d [%d][%d] = %g",i, p,N,T); + if(T > -100. && T < 100.){ // fill buffer + size_t l; + if(i == 0){ + buf = &ptrs[2]; len = &lens[2]; + // Nsens Npair T time + l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", N, p, T, + tmeasured[p][N][i]); + }else{ + buf = &ptrs[p]; len = &lens[p]; + // x y T time + l = snprintf(*buf, *len, "%d\t%d\t%.2f\t%ld\n", SensCoords[N][i][0], + SensCoords[N][i][1], T, tmeasured[p][N][i]); } + *len -= l; + *buf += l; } } } - 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]); tgot = dtime(); // copy temporary buffers to main pthread_mutex_lock(&mutex); diff --git a/src/netdaemon/term.c b/src/netdaemon/term.c index 3591b1c..9be7c34 100644 --- a/src/netdaemon/term.c +++ b/src/netdaemon/term.c @@ -159,6 +159,8 @@ static int send_cmd(int N, char cmd){ if(N < 0 || N > 7) return 1; char buf[4] = {(char)N + '0', cmd, '\n', 0}; char *rtn; + // clear all incomint data + while(read_string()); //DBG("send cmd %s", buf); if(write_tty(buf, 3)) return 1; if((rtn = read_string())){