diff --git a/Daemons/weather_proxy/Makefile b/Daemons/weather_proxy/Makefile index a7d1b84..132b553 100644 --- a/Daemons/weather_proxy/Makefile +++ b/Daemons/weather_proxy/Makefile @@ -1,10 +1,11 @@ CC = gcc -CFLAGS = -Wall -Wextra -fPIC -DEBUG +CFLAGS = -Wall -Wextra -fPIC +#-DEBUG LDFLAGS = -lrt -pthread -lusefull_macros -all: weather_daemon libweather.so weather_clt_example chkweather +all: weather_proxy libweather.so weather_clt_example chkweather -weather_daemon: weather_daemon.o +weather_proxy: weather_daemon.o $(CC) -o $@ $^ $(LDFLAGS) weather_clt_example: weather_clt_example.o @@ -32,8 +33,10 @@ chkweather.o: chkweather.c libweather.so $(CC) $(CFLAGS) -c $< clean: - rm -f *.o weather_daemon libweather.so libweather.a weather_clt_example + rm -f *.o weather_proxy chkweather libweather.so libweather.a weather_clt_example install: cp libweather.so /usr/local/lib/ cp weather_data.h /usr/local/include/ + cp chkweather weather_proxy /usr/local/bin + ldconfig diff --git a/Daemons/weather_proxy/chkweather.c b/Daemons/weather_proxy/chkweather.c index 0449b1f..8067027 100644 --- a/Daemons/weather_proxy/chkweather.c +++ b/Daemons/weather_proxy/chkweather.c @@ -27,10 +27,11 @@ int main() { struct tm *T = localtime(&wd.last_update); strftime(strt, 63, "%F %T", T); printf("Windmax=%.1f\nRain=%d\nClouds=%.1f\nWind=%.1f\nExttemp=%.1f\n" - "Pres=%.1f\nHumid=%.1f\nMeteo=local\nForceOFF=%d\n", + "Pres=%.1f\nHumid=%.1f\nMeteo=local\nForceOFF=%d\nWeather=%d\nWeatherTime=%d [%s]\n", wd.windmax, wd.rain, wd.clouds, wd.wind, wd.exttemp, - wd.pressure, wd.humidity, wd.forceoff); + wd.pressure, wd.humidity, wd.forceoff, (int)wd.weather, (int)wd.last_update, strt); if(!wd.forceoff) errcode = wd.weather; + if(time(NULL) - wd.last_update > 30) errcode = 3; }else{ fprintf(stderr, "Failed to get weather data\n"); } diff --git a/Daemons/weather_proxy/weather_daemon.c b/Daemons/weather_proxy/weather_daemon.c index 94cd996..4f6f6db 100644 --- a/Daemons/weather_proxy/weather_daemon.c +++ b/Daemons/weather_proxy/weather_daemon.c @@ -280,13 +280,13 @@ static void run_daemon(){ while(running){ time_t tnow = time(NULL); - int req = -1; + int req = -1, goterr = 0; if(sock) req = request_weather_data(sock); if(req == -1){ int diff = tnow - lastert; DBG("diff = %d", diff); if(diff > RECONN_TMOUT){ // try to reconnect - LOGERR("Failed to request weather data, retry"); + if(!goterr){ LOGERR("Failed to request weather data, retry"); goterr = 1; } if(sock) sl_sock_delete(&sock); if(!(sock = sl_sock_run_client(stype, G.node, 4096))){ new_data.weather = WEATHER_TERRIBLE; // no connection to weather server, don't allow to open @@ -298,6 +298,7 @@ static void run_daemon(){ } } }else if(req == 0) lastert = tnow; + else goterr = 0; while(sl_sock_readline(sock, line, 255) > 0){ DBG("Parse '%s'", line); diff --git a/Daemons/weatherdaemon_multimeteo/main.c b/Daemons/weatherdaemon_multimeteo/main.c index dc164b8..184b282 100644 --- a/Daemons/weatherdaemon_multimeteo/main.c +++ b/Daemons/weatherdaemon_multimeteo/main.c @@ -94,12 +94,6 @@ int main(int argc, char **argv){ signal(SIGPIPE, getpipe); // socket disconnected signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); - int nopened = openplugins(GP->plugins, GP->nplugins); - if(nopened < 1){ - LOGERR("No plugins found; exit!"); - ERRX("Can't find any sensor plugin"); - } - if(GP->nplugins && GP->nplugins != nopened) LOGWARN("Work without some plugins"); #ifndef EBUG sl_daemonize(); while(1){ // guard for dead processes @@ -117,6 +111,12 @@ int main(int argc, char **argv){ } } #endif + int nopened = openplugins(GP->plugins, GP->nplugins); + if(nopened < 1){ + LOGERR("No plugins found; exit!"); + ERRX("Can't find any sensor plugin"); + } + if(GP->nplugins && GP->nplugins != nopened) LOGWARN("Work without some plugins"); // react for USRx only in child signal(SIGUSR1, signals); signal(SIGUSR2, signals); diff --git a/Daemons/weatherdaemon_multimeteo/mainweather.c b/Daemons/weatherdaemon_multimeteo/mainweather.c index 79791de..75e1ba1 100644 --- a/Daemons/weatherdaemon_multimeteo/mainweather.c +++ b/Daemons/weatherdaemon_multimeteo/mainweather.c @@ -240,16 +240,17 @@ int collected_amount(){ int get_collected(val_t *val, int N){ if(!val || N < 0 || N >= NAMOUNT_OF_DATA + Nadditional){ - DBG("Wrong number (%d) requested or no place for data", N); + LOGWARN("get_collected(): wrong number (%d) requested or no place for data", N); return FALSE; } pthread_mutex_lock(&datamutex); val_t *dptr = (N < NAMOUNT_OF_DATA) ? &collected_data[N] : &additional_data[N-NAMOUNT_OF_DATA]; -#ifdef EBUG - char buf[KEY_LEN+1]; - get_fieldname(dptr, buf); - DBG("Copied data of %d (u=%d, nm=%s, t=%zd)", N, dptr->value.u, buf, dptr->time); -#endif + //LOGDBG("tm: %zd; cl: %zd", dptr->time, collected_data[N].time); +//#ifdef EBUG + //char buf[KEY_LEN+1]; + //get_fieldname(dptr, buf); + //LOGDBG("Copied data of %d (u=%d, nm=%s, t=%zd)", N, dptr->value.u, buf, dptr->time); +//#endif *val = *dptr; pthread_mutex_unlock(&datamutex); return TRUE; @@ -263,6 +264,7 @@ int get_collected(val_t *val, int N){ */ static void fix_new_data(val_t *collected, const val_t *fresh, int force){ if(!collected || !fresh) return; + //LOGDBG("fix_new_data(): collt: %zd, fresht: %zd", collected->time, fresh->time); if(collected->time >= fresh->time){ if(!force) return; //DBG("Forced, collected=%g, fresh=%g", val2d(collected), val2d(fresh)); @@ -270,10 +272,15 @@ static void fix_new_data(val_t *collected, const val_t *fresh, int force){ //DBG("Not too old"); } // lower `collected` level if data is too old - if(fresh->time - collected->time > WeatherConf.ahtung_delay) collected->sense = VAL_UNNECESSARY; + if(fresh->time - collected->time > WeatherConf.ahtung_delay){ + LOGDBG("collected val is too old -> mark as unnecessary"); + collected->sense = VAL_UNNECESSARY; + } + //LOGDBGADD("sense coll: %d, fresh: %d", collected->sense, fresh->sense); if(collected->sense < fresh->sense) return; if(collected->sense != fresh->sense) collected->sense = fresh->sense; // take new level //DBG("Refresh collected value"); + //LOGDBGADD("Refresh time"); collected->time = fresh->time; if(collected->type == fresh->type){ // good case memcpy(&collected->value, &fresh->value, sizeof(num_t)); @@ -337,7 +344,7 @@ static void update_additional(val_t *value){ ERR("realloc()"); } memcpy(&additional_data[idx], value, sizeof(val_t)); - DBG("Allocated new field: %s", value->name); + LOGDBG("Allocated new field: %s", value->name); }else fix_new_data(&additional_data[idx], value, 0); } @@ -402,9 +409,10 @@ static weather_cond_t const shtdnflag = {.good = 0.1, .bad = 0.5, .terrible = 0. void refresh_sensval(sensordata_t *s){ //FNAME(); //static time_t poll_time = 0; - static char reason[KEY_LEN+1] = {0}; // reason of weather level increasing + //LOGMSG("Refresh sensval for %d", s->PluginNo); + static char reason[VAL_LEN+1] = {0}; // reason of weather level increasing val_t value; - if(!s || !s->get_value) return; + if(!s || !sensor_alive(s) || !s->get_value) return; //if(poll_time == 0) poll_time = get_pollT(); static uint32_t curlevel = 0; // this is worse weather leavel, start from best (collect by all sensors through 3*tpoll) static time_t lasttupdate = 0; // last update time of weather level @@ -495,7 +503,7 @@ void refresh_sensval(sensordata_t *s){ if(curcond){ int oldshtdn = collected_data[NFORCEDSHTDN].value.u; if(1 == chkweatherlevel(&curlevel, curvalue, curcond)){ - get_fieldname(&value, reason); // copy to `reason` reason of last level increasing + get_fieldnameval(&value, reason); // copy to `reason` reason of last level increasing force = 1; DBG("reason: %s; forceflag=%u, old=%d", reason, collected_data[NFORCEDSHTDN].value.u, oldshtdn); if(collected_data[NFORCEDSHTDN].value.u - oldshtdn == 1){ // got shutdown @@ -505,7 +513,10 @@ void refresh_sensval(sensordata_t *s){ } if(idx == NFORCEDSHTDN && value.value.u == 0){ //DBG("Don't clear forced flag by other station"); - }else fix_new_data(&collected_data[idx], &value, force); + }else{ + //LOGDBG("Call fix_new_data for idx=%d (tcoll=%zd)", idx, collected_data[idx].time); + fix_new_data(&collected_data[idx], &value, force); + } pthread_mutex_unlock(&datamutex); } pthread_mutex_lock(&datamutex); @@ -519,6 +530,7 @@ void refresh_sensval(sensordata_t *s){ collected_data[NWINDDIR2].time = curtime; } if(curtime - collected_data[NWIND].time < tpoll + 1){ + //LOGDBG("Update max wind"); collected_data[NWINDMAX].value.f = (float) get_current_max(&windspeeds); collected_data[NWINDMAX].time = curtime; collected_data[NWINDMAX1].value.f = (float) get_max_forT(&windspeeds, curtime - T_ONE_HOUR); @@ -526,6 +538,7 @@ void refresh_sensval(sensordata_t *s){ } //DBG("check ahtung"); time_t _2update = lasttupdate + _3tpoll; + //LOGDBG("curtime: %ld, _2update: %ld", curtime, lasttupdate); if(Forbidden){ collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED; collected_data[NCOMMWEATH].time = curtime; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/CMakeLists.txt b/Daemons/weatherdaemon_multimeteo/plugins/CMakeLists.txt index 10e1ce1..6eb517e 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/CMakeLists.txt +++ b/Daemons/weatherdaemon_multimeteo/plugins/CMakeLists.txt @@ -64,3 +64,7 @@ if(LIGHTNING) endif() install(TARGETS ${LIBS} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(CODE [===[ + message(STATUS "Run ldconfig") + execute_process(COMMAND ldconfig) + ]===]) diff --git a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c index f52ddb1..874873e 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c @@ -59,8 +59,6 @@ static void *mainthread(void *s){ }else break; // no connection? sleep(1); } - DBG("Lost connection -> suicide"); - sensor->kill(sensor); return NULL; } @@ -69,7 +67,6 @@ int sensor_init(sensordata_t *s){ if(!s) return FALSE; if(!get_shm_block(&sdat, ClientSide)){ WARNX("Can't get BTA shared memory block or create main thread"); - s->kill(s); return FALSE; } s->values = MALLOC(val_t, NAMOUNT); @@ -78,7 +75,6 @@ int sensor_init(sensordata_t *s){ strncpy(s->name, SENSOR_NAME, NAME_LEN); if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){ WARN("Can't create main thread"); - s->kill(s); return FALSE; } s->fdes = 0; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/dummy.c b/Daemons/weatherdaemon_multimeteo/plugins/dummy.c index 5828f2b..54571c2 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/dummy.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/dummy.c @@ -84,7 +84,6 @@ int sensor_init(sensordata_t *s){ s->values[5].value.u = 0; //s->values[6].value.f = 4.5; if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } s->fdes = 0; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/fdexample.c b/Daemons/weatherdaemon_multimeteo/plugins/fdexample.c index 119cfaa..8288674 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/fdexample.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/fdexample.c @@ -115,8 +115,7 @@ static void *mainthread(void *s){ } } } - DBG("OOOOps!"); - sensor->kill(sensor); + // newer use `kill` here! Master will run it after main thread death return NULL; } @@ -132,11 +131,9 @@ int sensor_init(sensordata_t *s){ for(int i = 0; i < NS; ++i) s->values[i] = values[i]; if(!(s->ringbuffer = sl_RB_new(BUFSIZ))){ WARNX("Can't init ringbuffer!"); - s->kill(s); return FALSE; } if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/hydreon.c b/Daemons/weatherdaemon_multimeteo/plugins/hydreon.c index 17dc187..c0b3222 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/hydreon.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/hydreon.c @@ -99,11 +99,11 @@ enum{ static const val_t values[NAMOUNT] = { // fields `name` and `comment` have no sense until value meaning is `IS_OTHER` [NPRECIP] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_PRECIP}, [NPRECIP_LEVEL] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, - [NSINCERN] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "TSINCERN", .comment = "Minutes since rain (20 means a lot of)"}, - [NPOW] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RAINPOW", .comment = "Rain strength, 0..255"}, - [NAVG] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RAINAVG", .comment = "Average rain strength, 0..255"}, - [NAMBL] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RSAMBL", .comment = "Ambient light by rain sensor, 0..255"}, - [NFREEZ] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RSFREEZ", .comment = "Rain sensor is freezed"}, + [NSINCERN] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "TSINCERN", .comment = "Minutes since rain (20 means a lot of)"}, + [NPOW] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RAINPOW", .comment = "Rain strength, 0..255"}, + [NAVG] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RAINAVG", .comment = "Average rain strength, 0..255"}, + [NAMBL] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RSAMBL", .comment = "Ambient light by rain sensor, 0..255"}, + [NFREEZ] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "RSFREEZ", .comment = "Rain sensor is freezed"}, }; static int getv(char s, uint8_t *v){ @@ -119,7 +119,7 @@ static int getv(char s, uint8_t *v){ } static int encodepacket(const char *buf, int len, rg11 *Rregs, slowregs *Sregs){ - DBG("got buffer: %s[%d]", buf, len); +// DBG("got buffer: %s[%d]", buf, len); uint8_t databuf[REGLEN/2] = {0}; static slowregs slow = {0}; if(len != REGMINLEN && len != REGLEN){ @@ -172,7 +172,7 @@ static void *mainthread(void *s){ if(got > 0){ buf[--got] = 0; if(encodepacket(buf, got, &Rregs, &Sregs)){ - DBG("refresh..."); + //DBG("refresh..."); pthread_mutex_lock(&sensor->valmutex); for(int i = 0; i < NAMOUNT; ++i) sensor->values[i].time = tnow; @@ -189,8 +189,6 @@ static void *mainthread(void *s){ } } } - DBG("OOOOps!"); - sensor->kill(sensor); return NULL; } @@ -207,7 +205,6 @@ int sensor_init(sensordata_t *s){ for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i]; if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) || pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/lightning.c b/Daemons/weatherdaemon_multimeteo/plugins/lightning.c index 59af6e2..1b0b73a 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/lightning.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/lightning.c @@ -176,8 +176,6 @@ static void *mainthread(void *s){ } usleep(1000); } - DBG("suicide"); - sensor->kill(sensor); return NULL; } @@ -194,7 +192,6 @@ int sensor_init(sensordata_t *s){ for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i]; if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) || pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c b/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c index a7839ce..a91f0b0 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c @@ -39,9 +39,9 @@ enum{ static const val_t values[NAMOUNT] = { [NWIND] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_WIND}, [NWINDDIR] = {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_WINDDIR}, - [NHUMIDITY] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_HUMIDITY}, + [NHUMIDITY] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_HUMIDITY}, // broken on our meteostation [NAMB_TEMP] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP}, - [NPRESSURE] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_PRESSURE}, + [NPRESSURE] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_PRESSURE}, // broken on our meteostation [NCLOUDS] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_CLOUDS}, [NPRECIP] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_PRECIP}, [NPRECIPLVL]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, @@ -161,7 +161,6 @@ static void *mainthread(void *s){ if(sensor->freshdatahandler) sensor->freshdatahandler(sensor); } } - sensor->kill(sensor); return NULL; } @@ -178,7 +177,6 @@ int sensor_init(sensordata_t *s){ for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i]; if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) || pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/snmp.c b/Daemons/weatherdaemon_multimeteo/plugins/snmp.c index bc2bf75..16d5806 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/snmp.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/snmp.c @@ -192,9 +192,9 @@ int sensor_init(sensordata_t *s){ snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME); s->fdes = 0; - s->Nvalues = NAMOUNT; s->values = MALLOC(val_t, NAMOUNT); for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i]; + s->Nvalues = NAMOUNT; DBG("init OIDs"); for(int i = 0; i < OID_AMOUNT; ++i){ @@ -209,7 +209,6 @@ int sensor_init(sensordata_t *s){ DBG("Start main thread"); if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) || pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c b/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c index 29fc6b5..29cb8e6 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c @@ -43,9 +43,9 @@ static const val_t values[NAMOUNT] = { [NHUMIDITY] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_HUMIDITY}, [NAMB_TEMP] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP}, [NPRESSURE] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_PRESSURE}, - [NPRECIP] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_PRECIP}, - [NPRECIPLVL]= {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, - [NPRECIPINT]= {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_OTHER, .name = "PRECRATE", .comment = "Precipitation rate, mm/h"}, + [NPRECIP] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_PRECIP}, // this sensor lies + [NPRECIPLVL]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, + [NPRECIPINT]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_OTHER, .name = "PRECRATE", .comment = "Precipitation rate, mm/h"}, }; typedef struct{ @@ -106,7 +106,7 @@ static int parseans(char *str){ }else{ *el->weatherpar = strtod(token, &endptr); if(endptr == token){ - DBG("Wrong double value %s", token); + // DBG("Wrong double value %s", token); }else ++ncollected; } break; @@ -115,7 +115,7 @@ static int parseans(char *str){ } token = strtok(NULL, ","); } - DBG("Got %d values", ncollected); + // DBG("Got %d values", ncollected); return ncollected; } @@ -131,7 +131,7 @@ static void *mainthread(void *s){ WARN("Can't ask new data"); break; } - DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll); +// DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll); tpoll = tnow; } int canread = sl_canread(sensor->fdes); @@ -190,7 +190,7 @@ static void *mainthread(void *s){ if(sensor->freshdatahandler) sensor->freshdatahandler(sensor); } } - sensor->kill(sensor); + // newer use `kill` here! Master will run it after main thread death return NULL; } @@ -201,12 +201,11 @@ int sensor_init(sensordata_t *s){ if(fd < 0) return FALSE; snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME); s->fdes = fd; - s->Nvalues = NAMOUNT; s->values = MALLOC(val_t, NAMOUNT); for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i]; + s->Nvalues = NAMOUNT; if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) || pthread_create(&s->thread, NULL, mainthread, (void*)s)){ - s->kill(s); return FALSE; } return TRUE; diff --git a/Daemons/weatherdaemon_multimeteo/sensors.c b/Daemons/weatherdaemon_multimeteo/sensors.c index 4c6e36c..d81c24a 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.c +++ b/Daemons/weatherdaemon_multimeteo/sensors.c @@ -56,7 +56,9 @@ time_t get_pollT(){ return poll_interval;} */ sensordata_t *get_plugin(int N){ if(N < 0 || N >= nplugins) return NULL; - return allplugins[N]; + sensordata_t *s = allplugins[N]; + if(!s || !sensor_alive(s)) s = NULL; + return s; } // TODO: fix for usage with several identical meteostations @@ -85,7 +87,17 @@ void *open_plugin(const char *name){ */ static void dumpsensors(struct sensordata_t* station){ //FNAME(); - if(!sensor_alive(station) || !station->get_value || station->Nvalues < 1 || station->IsMuted) return; + if(!station){ + LOGERR("(null) in dumpsensors' station"); + return; + } + /* + LOGMSG("alive: %d[%d]", sensor_alive(station), station->PluginNo); + LOGMSGADD("getvalue: %s", station->get_value ? "yes" : "no"); + LOGMSGADD("nvalues: %d", station->Nvalues); + LOGMSGADD("ismuted: %d", station->IsMuted); + */ + if(station->Nvalues < 1 || station->IsMuted) return; refresh_sensval(station); #if 0 DBG("New values..."); @@ -124,12 +136,12 @@ int openplugins(char **paths, int N){ char buf[PATH_MAX+1]; if(!paths || !*paths || N < 1) return 0; if(allplugins || nplugins){ - WARNXL("Plugins already opened"); return 0; + LOGWARN("Plugins already opened"); return 0; } allplugins = MALLOC(sensordata_t*, N); - green("Try to open plugins:\n"); + LOGMSG("Try to open plugins:"); for(int i = 0; i < N; ++i){ - printf("\tplugin[%d]=%s\n", i, paths[i]); + LOGMSGADD("plugin[%d]=%s\n", i, paths[i]); snprintf(buf, PATH_MAX, "%s", paths[i]); char *colon = strchr(buf, ':'); if(colon) *colon++ = 0; @@ -145,10 +157,12 @@ int openplugins(char **paths, int N){ S->tpoll = poll_interval; allplugins[nplugins++] = S; int inited = sensinit(S); // here nplugins is index in array - if(!inited) WARNXL("Can't init plugin %s", paths[i]); - else{ + if(!inited){ + WARNXL("Can't init plugin %s", paths[i]); + if(S->kill) S->kill(S); + }else{ if(!S->onrefresh || !S->onrefresh(S, dumpsensors)) WARNXL("Can't init refresh funtion"); - LOGMSG("Plugin %s nave %d sensors", paths[i], S->Nvalues); + LOGMSGADD("Plugin %s nave %d sensors; file descriptor: %d", paths[i], S->Nvalues, S->fdes); } } }else WARNXL("Can't find initing function in plugin %s: %s", paths[i], dlerror()); @@ -165,6 +179,7 @@ void closeplugins(){ for(int i = 0; i < nplugins; ++i){ if(allplugins[i]->kill) allplugins[i]->kill(allplugins[i]); FREE(allplugins[i]); + LOGWARN("Plugin %d killed", i); } FREE(allplugins); nplugins = 0; @@ -197,6 +212,7 @@ int format_senssense(const val_t *v, char *buf, int buflen, int Np){ return (got < buflen) ? got : buflen; // full or truncated } +// put to `buf` string with sensor's name void get_fieldname(const val_t *v, char buf[KEY_LEN+1]){ if(!v || !buf) return; int idx = v->meaning; @@ -210,6 +226,20 @@ void get_fieldname(const val_t *v, char buf[KEY_LEN+1]){ else buf[0] = 0; // empty } +// put to `buf` string "name=value" +void get_fieldnameval(const val_t *v, char buf[VAL_LEN+1]){ + if(!v || !buf) return; + int idx = v->meaning; + const char *name = NULL; + if(idx < IS_OTHER){ + name = NM[idx]; + }else{ + name = v->name; + } + if(name) snprintf(buf, VAL_LEN+1, "%s=%g", name, val2d(v)); + else buf[0] = 0; // empty +} + /** * @brief format_sensval - snprintf sensor's value into buffer * @param v - value to get diff --git a/Daemons/weatherdaemon_multimeteo/sensors.h b/Daemons/weatherdaemon_multimeteo/sensors.h index 86a888c..90ec0e9 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.h +++ b/Daemons/weatherdaemon_multimeteo/sensors.h @@ -41,6 +41,7 @@ time_t get_pollT(); double val2d(const val_t *v); void get_fieldname(const val_t *v, char buf[KEY_LEN+1]); +void get_fieldnameval(const val_t *v, char buf[VAL_LEN+1]); int station_mute(sensordata_t *s); int station_unmute(sensordata_t *s); diff --git a/Daemons/weatherdaemon_multimeteo/server.c b/Daemons/weatherdaemon_multimeteo/server.c index 1f35db8..00cfa96 100644 --- a/Daemons/weatherdaemon_multimeteo/server.c +++ b/Daemons/weatherdaemon_multimeteo/server.c @@ -40,18 +40,24 @@ static sl_sock_hresult_e timehandler(sl_sock_t *client, _U_ sl_sock_hitem_t *ite } #define SSZ_ (PATH_MAX + 256) +static void send_plugin_name(int N, sensordata_t *d, sl_sock_t *client){ + if(!d || !client) return; + char buf[SSZ_]; + if(d->path[0]) snprintf(buf, SSZ_, "PLUGIN[%d]=%s @ %s\nNVALUES[%d]=%d\n", N, d->name, d->path, N, d->Nvalues); + else snprintf(buf, SSZ_, "PLUGIN[%d]=%s\nNVALUES[%d]=%d\n", N, d->name, N, d->Nvalues); + sl_sock_sendstrmessage(client, buf); +} + // show all connected libraries static sl_sock_hresult_e listhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item, _U_ const char *req){ if(!client) return RESULT_FAIL; - char buf[SSZ_]; + int N = get_nplugins(); if(N < 1) return RESULT_FAIL; sensordata_t *d = NULL; for(int i = 0; i < N; ++i){ if(!(d = get_plugin(i))) continue; - if(d->path[0]) snprintf(buf, SSZ_, "PLUGIN[%d]=%s @ %s\nNVALUES[%d]=%d\n", i, d->name, d->path, i, d->Nvalues); - else snprintf(buf, SSZ_, "PLUGIN[%d]=%s\nNVALUES[%d]=%d\n", i, d->name, i, d->Nvalues); - sl_sock_sendstrmessage(client, buf); + send_plugin_name(i, d, client); } return RESULT_SILENCE; } @@ -65,6 +71,7 @@ sensordata_t *get_plugin_w_message(sl_sock_t *client, int N){ sl_sock_sendstrmessage(client, buf); return NULL; } + send_plugin_name(N, s, client); return s; } @@ -403,16 +410,19 @@ int start_servers(const char *netnode, const char *sockpath){ if(!s) continue; if(sensor_alive(s)) continue; // sensor isn't inited - try to do it - DBG("sensor with path %s isn't inited, try", s->path); + LOGWARN("Sensor %s isn't alive, kill and try to reinit", s->path); s->kill(s); // clear resources if(s->init){ - if(s->init(s)) LOGMSG("Sensor %s reinited @ %s", s->name, s->path); - else DBG("Can't reinit"); + if(s->init(s)){ + if(s->path[0]) LOGMSG("Sensor %s reinited @ %s", s->name, s->path); + else LOGMSG("Sensor %s reinited", s->name); + }else LOGWARN("Can't reinit"); } } while((tcur = time(NULL)) - tstart < WeatherConf.reinit_delay) sleep(1); tstart = tcur; } + LOGERR("start_servers(): never reacheable point reached"); return TRUE; // should be never reached } diff --git a/Daemons/weatherdaemon_multimeteo/weathlib.c b/Daemons/weatherdaemon_multimeteo/weathlib.c index 3861c48..a09a6ea 100644 --- a/Daemons/weatherdaemon_multimeteo/weathlib.c +++ b/Daemons/weatherdaemon_multimeteo/weathlib.c @@ -40,7 +40,8 @@ sensordata_t *sensor_new(int N, const char *descr){ s->get_value = common_getval; s->kill = common_kill; s->PluginNo = N; // `init` shouldn't change this value - snprintf(s->path, PATH_MAX, "%s", descr); // `init` shouldn't change this value + if(descr && *descr) snprintf(s->path, PATH_MAX, "%s", descr); // `init` shouldn't change this value + else s->path[0] = 0; // no path pthread_mutex_init(&s->valmutex, NULL); return s; } @@ -51,8 +52,15 @@ sensordata_t *sensor_new(int N, const char *descr){ * @return FALSE if thread is dead */ int sensor_alive(sensordata_t *s){ - if(!s || s->fdes < 0) return FALSE; - if(pthread_kill(s->thread, 0)) return FALSE; + if(!s || s->fdes < 0){ + LOGMSG("No sensor or fdes < 0"); + return FALSE; + } + if(pthread_kill(s->thread, 0)){ + if(s->path[0]) LOGMSG("Sensor's '%s @ %s' main thread is dead", s->name, s->path); + else LOGMSG("Sensor's '%s' main thread is dead", s->name); + return FALSE; + } return TRUE; } @@ -94,6 +102,7 @@ void common_kill(sensordata_t *s){ DBG("Delete RB"); if(s->ringbuffer) sl_RB_delete(&s->ringbuffer); FREE(s->values); + s->Nvalues = 0; if(s->privdatafree) s->privdatafree(s->privdata); else FREE(s->privdata); DBG("Sensor '%s' killed", s->name);