mirror of
https://github.com/eddyem/small_tel.git
synced 2026-06-19 10:26:25 +03:00
fixed some bugs, check @ real system
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -fPIC -DEBUG
|
CFLAGS = -Wall -Wextra -fPIC
|
||||||
|
#-DEBUG
|
||||||
LDFLAGS = -lrt -pthread -lusefull_macros
|
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)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
weather_clt_example: weather_clt_example.o
|
weather_clt_example: weather_clt_example.o
|
||||||
@@ -32,8 +33,10 @@ chkweather.o: chkweather.c libweather.so
|
|||||||
$(CC) $(CFLAGS) -c $<
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
clean:
|
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:
|
install:
|
||||||
cp libweather.so /usr/local/lib/
|
cp libweather.so /usr/local/lib/
|
||||||
cp weather_data.h /usr/local/include/
|
cp weather_data.h /usr/local/include/
|
||||||
|
cp chkweather weather_proxy /usr/local/bin
|
||||||
|
ldconfig
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ int main() {
|
|||||||
struct tm *T = localtime(&wd.last_update);
|
struct tm *T = localtime(&wd.last_update);
|
||||||
strftime(strt, 63, "%F %T", T);
|
strftime(strt, 63, "%F %T", T);
|
||||||
printf("Windmax=%.1f\nRain=%d\nClouds=%.1f\nWind=%.1f\nExttemp=%.1f\n"
|
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.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(!wd.forceoff) errcode = wd.weather;
|
||||||
|
if(time(NULL) - wd.last_update > 30) errcode = 3;
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "Failed to get weather data\n");
|
fprintf(stderr, "Failed to get weather data\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,13 +280,13 @@ static void run_daemon(){
|
|||||||
|
|
||||||
while(running){
|
while(running){
|
||||||
time_t tnow = time(NULL);
|
time_t tnow = time(NULL);
|
||||||
int req = -1;
|
int req = -1, goterr = 0;
|
||||||
if(sock) req = request_weather_data(sock);
|
if(sock) req = request_weather_data(sock);
|
||||||
if(req == -1){
|
if(req == -1){
|
||||||
int diff = tnow - lastert;
|
int diff = tnow - lastert;
|
||||||
DBG("diff = %d", diff);
|
DBG("diff = %d", diff);
|
||||||
if(diff > RECONN_TMOUT){ // try to reconnect
|
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_delete(&sock);
|
||||||
if(!(sock = sl_sock_run_client(stype, G.node, 4096))){
|
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
|
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 if(req == 0) lastert = tnow;
|
||||||
|
else goterr = 0;
|
||||||
|
|
||||||
while(sl_sock_readline(sock, line, 255) > 0){
|
while(sl_sock_readline(sock, line, 255) > 0){
|
||||||
DBG("Parse '%s'", line);
|
DBG("Parse '%s'", line);
|
||||||
|
|||||||
@@ -94,12 +94,6 @@ int main(int argc, char **argv){
|
|||||||
signal(SIGPIPE, getpipe); // socket disconnected
|
signal(SIGPIPE, getpipe); // socket disconnected
|
||||||
signal(SIGUSR1, SIG_IGN);
|
signal(SIGUSR1, SIG_IGN);
|
||||||
signal(SIGUSR2, 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
|
#ifndef EBUG
|
||||||
sl_daemonize();
|
sl_daemonize();
|
||||||
while(1){ // guard for dead processes
|
while(1){ // guard for dead processes
|
||||||
@@ -117,6 +111,12 @@ int main(int argc, char **argv){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
// react for USRx only in child
|
||||||
signal(SIGUSR1, signals);
|
signal(SIGUSR1, signals);
|
||||||
signal(SIGUSR2, signals);
|
signal(SIGUSR2, signals);
|
||||||
|
|||||||
@@ -240,16 +240,17 @@ int collected_amount(){
|
|||||||
|
|
||||||
int get_collected(val_t *val, int N){
|
int get_collected(val_t *val, int N){
|
||||||
if(!val || N < 0 || N >= NAMOUNT_OF_DATA + Nadditional){
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&datamutex);
|
pthread_mutex_lock(&datamutex);
|
||||||
val_t *dptr = (N < NAMOUNT_OF_DATA) ? &collected_data[N] : &additional_data[N-NAMOUNT_OF_DATA];
|
val_t *dptr = (N < NAMOUNT_OF_DATA) ? &collected_data[N] : &additional_data[N-NAMOUNT_OF_DATA];
|
||||||
#ifdef EBUG
|
//LOGDBG("tm: %zd; cl: %zd", dptr->time, collected_data[N].time);
|
||||||
char buf[KEY_LEN+1];
|
//#ifdef EBUG
|
||||||
get_fieldname(dptr, buf);
|
//char buf[KEY_LEN+1];
|
||||||
DBG("Copied data of %d (u=%d, nm=%s, t=%zd)", N, dptr->value.u, buf, dptr->time);
|
//get_fieldname(dptr, buf);
|
||||||
#endif
|
//LOGDBG("Copied data of %d (u=%d, nm=%s, t=%zd)", N, dptr->value.u, buf, dptr->time);
|
||||||
|
//#endif
|
||||||
*val = *dptr;
|
*val = *dptr;
|
||||||
pthread_mutex_unlock(&datamutex);
|
pthread_mutex_unlock(&datamutex);
|
||||||
return TRUE;
|
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){
|
static void fix_new_data(val_t *collected, const val_t *fresh, int force){
|
||||||
if(!collected || !fresh) return;
|
if(!collected || !fresh) return;
|
||||||
|
//LOGDBG("fix_new_data(): collt: %zd, fresht: %zd", collected->time, fresh->time);
|
||||||
if(collected->time >= fresh->time){
|
if(collected->time >= fresh->time){
|
||||||
if(!force) return;
|
if(!force) return;
|
||||||
//DBG("Forced, collected=%g, fresh=%g", val2d(collected), val2d(fresh));
|
//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");
|
//DBG("Not too old");
|
||||||
}
|
}
|
||||||
// lower `collected` level if data is 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) return;
|
||||||
if(collected->sense != fresh->sense) collected->sense = fresh->sense; // take new level
|
if(collected->sense != fresh->sense) collected->sense = fresh->sense; // take new level
|
||||||
//DBG("Refresh collected value");
|
//DBG("Refresh collected value");
|
||||||
|
//LOGDBGADD("Refresh time");
|
||||||
collected->time = fresh->time;
|
collected->time = fresh->time;
|
||||||
if(collected->type == fresh->type){ // good case
|
if(collected->type == fresh->type){ // good case
|
||||||
memcpy(&collected->value, &fresh->value, sizeof(num_t));
|
memcpy(&collected->value, &fresh->value, sizeof(num_t));
|
||||||
@@ -337,7 +344,7 @@ static void update_additional(val_t *value){
|
|||||||
ERR("realloc()");
|
ERR("realloc()");
|
||||||
}
|
}
|
||||||
memcpy(&additional_data[idx], value, sizeof(val_t));
|
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);
|
}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){
|
void refresh_sensval(sensordata_t *s){
|
||||||
//FNAME();
|
//FNAME();
|
||||||
//static time_t poll_time = 0;
|
//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;
|
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();
|
//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 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
|
static time_t lasttupdate = 0; // last update time of weather level
|
||||||
@@ -495,7 +503,7 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
if(curcond){
|
if(curcond){
|
||||||
int oldshtdn = collected_data[NFORCEDSHTDN].value.u;
|
int oldshtdn = collected_data[NFORCEDSHTDN].value.u;
|
||||||
if(1 == chkweatherlevel(&curlevel, curvalue, curcond)){
|
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;
|
force = 1;
|
||||||
DBG("reason: %s; forceflag=%u, old=%d", reason, collected_data[NFORCEDSHTDN].value.u, oldshtdn);
|
DBG("reason: %s; forceflag=%u, old=%d", reason, collected_data[NFORCEDSHTDN].value.u, oldshtdn);
|
||||||
if(collected_data[NFORCEDSHTDN].value.u - oldshtdn == 1){ // got shutdown
|
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){
|
if(idx == NFORCEDSHTDN && value.value.u == 0){
|
||||||
//DBG("Don't clear forced flag by other station");
|
//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_unlock(&datamutex);
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&datamutex);
|
pthread_mutex_lock(&datamutex);
|
||||||
@@ -519,6 +530,7 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
collected_data[NWINDDIR2].time = curtime;
|
collected_data[NWINDDIR2].time = curtime;
|
||||||
}
|
}
|
||||||
if(curtime - collected_data[NWIND].time < tpoll + 1){
|
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].value.f = (float) get_current_max(&windspeeds);
|
||||||
collected_data[NWINDMAX].time = curtime;
|
collected_data[NWINDMAX].time = curtime;
|
||||||
collected_data[NWINDMAX1].value.f = (float) get_max_forT(&windspeeds, curtime - T_ONE_HOUR);
|
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");
|
//DBG("check ahtung");
|
||||||
time_t _2update = lasttupdate + _3tpoll;
|
time_t _2update = lasttupdate + _3tpoll;
|
||||||
|
//LOGDBG("curtime: %ld, _2update: %ld", curtime, lasttupdate);
|
||||||
if(Forbidden){
|
if(Forbidden){
|
||||||
collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED;
|
collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED;
|
||||||
collected_data[NCOMMWEATH].time = curtime;
|
collected_data[NCOMMWEATH].time = curtime;
|
||||||
|
|||||||
@@ -64,3 +64,7 @@ if(LIGHTNING)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(TARGETS ${LIBS} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(TARGETS ${LIBS} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
install(CODE [===[
|
||||||
|
message(STATUS "Run ldconfig")
|
||||||
|
execute_process(COMMAND ldconfig)
|
||||||
|
]===])
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ static void *mainthread(void *s){
|
|||||||
}else break; // no connection?
|
}else break; // no connection?
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
DBG("Lost connection -> suicide");
|
|
||||||
sensor->kill(sensor);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +67,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
if(!s) return FALSE;
|
if(!s) return FALSE;
|
||||||
if(!get_shm_block(&sdat, ClientSide)){
|
if(!get_shm_block(&sdat, ClientSide)){
|
||||||
WARNX("Can't get BTA shared memory block or create main thread");
|
WARNX("Can't get BTA shared memory block or create main thread");
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
s->values = MALLOC(val_t, NAMOUNT);
|
s->values = MALLOC(val_t, NAMOUNT);
|
||||||
@@ -78,7 +75,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
strncpy(s->name, SENSOR_NAME, NAME_LEN);
|
strncpy(s->name, SENSOR_NAME, NAME_LEN);
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
WARN("Can't create main thread");
|
WARN("Can't create main thread");
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
s->fdes = 0;
|
s->fdes = 0;
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
s->values[5].value.u = 0;
|
s->values[5].value.u = 0;
|
||||||
//s->values[6].value.f = 4.5;
|
//s->values[6].value.f = 4.5;
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
s->fdes = 0;
|
s->fdes = 0;
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ static void *mainthread(void *s){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBG("OOOOps!");
|
// newer use `kill` here! Master will run it after main thread death
|
||||||
sensor->kill(sensor);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,11 +131,9 @@ int sensor_init(sensordata_t *s){
|
|||||||
for(int i = 0; i < NS; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NS; ++i) s->values[i] = values[i];
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ))){
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ))){
|
||||||
WARNX("Can't init ringbuffer!");
|
WARNX("Can't init ringbuffer!");
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -99,11 +99,11 @@ enum{
|
|||||||
static const val_t values[NAMOUNT] = { // fields `name` and `comment` have no sense until value meaning is `IS_OTHER`
|
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] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_PRECIP},
|
||||||
[NPRECIP_LEVEL] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL},
|
[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)"},
|
[NSINCERN] = {.sense = VAL_RECOMMENDED, .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"},
|
[NPOW] = {.sense = VAL_RECOMMENDED, .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"},
|
[NAVG] = {.sense = VAL_RECOMMENDED, .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"},
|
[NAMBL] = {.sense = VAL_RECOMMENDED, .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"},
|
[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){
|
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){
|
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};
|
uint8_t databuf[REGLEN/2] = {0};
|
||||||
static slowregs slow = {0};
|
static slowregs slow = {0};
|
||||||
if(len != REGMINLEN && len != REGLEN){
|
if(len != REGMINLEN && len != REGLEN){
|
||||||
@@ -172,7 +172,7 @@ static void *mainthread(void *s){
|
|||||||
if(got > 0){
|
if(got > 0){
|
||||||
buf[--got] = 0;
|
buf[--got] = 0;
|
||||||
if(encodepacket(buf, got, &Rregs, &Sregs)){
|
if(encodepacket(buf, got, &Rregs, &Sregs)){
|
||||||
DBG("refresh...");
|
//DBG("refresh...");
|
||||||
pthread_mutex_lock(&sensor->valmutex);
|
pthread_mutex_lock(&sensor->valmutex);
|
||||||
for(int i = 0; i < NAMOUNT; ++i)
|
for(int i = 0; i < NAMOUNT; ++i)
|
||||||
sensor->values[i].time = tnow;
|
sensor->values[i].time = tnow;
|
||||||
@@ -189,8 +189,6 @@ static void *mainthread(void *s){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBG("OOOOps!");
|
|
||||||
sensor->kill(sensor);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +205,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
||||||
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -176,8 +176,6 @@ static void *mainthread(void *s){
|
|||||||
}
|
}
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
DBG("suicide");
|
|
||||||
sensor->kill(sensor);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +192,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
||||||
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ enum{
|
|||||||
static const val_t values[NAMOUNT] = {
|
static const val_t values[NAMOUNT] = {
|
||||||
[NWIND] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_WIND},
|
[NWIND] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_WIND},
|
||||||
[NWINDDIR] = {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_WINDDIR},
|
[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},
|
[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},
|
[NCLOUDS] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_CLOUDS},
|
||||||
[NPRECIP] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_PRECIP},
|
[NPRECIP] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_PRECIP},
|
||||||
[NPRECIPLVL]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL},
|
[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);
|
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sensor->kill(sensor);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +177,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
||||||
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -192,9 +192,9 @@ int sensor_init(sensordata_t *s){
|
|||||||
|
|
||||||
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
s->fdes = 0;
|
s->fdes = 0;
|
||||||
s->Nvalues = NAMOUNT;
|
|
||||||
s->values = MALLOC(val_t, NAMOUNT);
|
s->values = MALLOC(val_t, NAMOUNT);
|
||||||
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
||||||
|
s->Nvalues = NAMOUNT;
|
||||||
|
|
||||||
DBG("init OIDs");
|
DBG("init OIDs");
|
||||||
for(int i = 0; i < OID_AMOUNT; ++i){
|
for(int i = 0; i < OID_AMOUNT; ++i){
|
||||||
@@ -209,7 +209,6 @@ int sensor_init(sensordata_t *s){
|
|||||||
DBG("Start main thread");
|
DBG("Start main thread");
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
||||||
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ static const val_t values[NAMOUNT] = {
|
|||||||
[NHUMIDITY] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_HUMIDITY},
|
[NHUMIDITY] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_HUMIDITY},
|
||||||
[NAMB_TEMP] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP},
|
[NAMB_TEMP] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP},
|
||||||
[NPRESSURE] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_PRESSURE},
|
[NPRESSURE] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_PRESSURE},
|
||||||
[NPRECIP] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_PRECIP},
|
[NPRECIP] = {.sense = VAL_UNNECESSARY, .type = VALT_UINT, .meaning = IS_PRECIP}, // this sensor lies
|
||||||
[NPRECIPLVL]= {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL},
|
[NPRECIPLVL]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL},
|
||||||
[NPRECIPINT]= {.sense = VAL_RECOMMENDED,.type = VALT_FLOAT, .meaning = IS_OTHER, .name = "PRECRATE", .comment = "Precipitation rate, mm/h"},
|
[NPRECIPINT]= {.sense = VAL_UNNECESSARY,.type = VALT_FLOAT, .meaning = IS_OTHER, .name = "PRECRATE", .comment = "Precipitation rate, mm/h"},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
@@ -106,7 +106,7 @@ static int parseans(char *str){
|
|||||||
}else{
|
}else{
|
||||||
*el->weatherpar = strtod(token, &endptr);
|
*el->weatherpar = strtod(token, &endptr);
|
||||||
if(endptr == token){
|
if(endptr == token){
|
||||||
DBG("Wrong double value %s", token);
|
// DBG("Wrong double value %s", token);
|
||||||
}else ++ncollected;
|
}else ++ncollected;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -115,7 +115,7 @@ static int parseans(char *str){
|
|||||||
}
|
}
|
||||||
token = strtok(NULL, ",");
|
token = strtok(NULL, ",");
|
||||||
}
|
}
|
||||||
DBG("Got %d values", ncollected);
|
// DBG("Got %d values", ncollected);
|
||||||
return ncollected;
|
return ncollected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ static void *mainthread(void *s){
|
|||||||
WARN("Can't ask new data");
|
WARN("Can't ask new data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll);
|
// DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll);
|
||||||
tpoll = tnow;
|
tpoll = tnow;
|
||||||
}
|
}
|
||||||
int canread = sl_canread(sensor->fdes);
|
int canread = sl_canread(sensor->fdes);
|
||||||
@@ -190,7 +190,7 @@ static void *mainthread(void *s){
|
|||||||
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sensor->kill(sensor);
|
// newer use `kill` here! Master will run it after main thread death
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,12 +201,11 @@ int sensor_init(sensordata_t *s){
|
|||||||
if(fd < 0) return FALSE;
|
if(fd < 0) return FALSE;
|
||||||
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
s->Nvalues = NAMOUNT;
|
|
||||||
s->values = MALLOC(val_t, NAMOUNT);
|
s->values = MALLOC(val_t, NAMOUNT);
|
||||||
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NAMOUNT; ++i) s->values[i] = values[i];
|
||||||
|
s->Nvalues = NAMOUNT;
|
||||||
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
if(!(s->ringbuffer = sl_RB_new(BUFSIZ)) ||
|
||||||
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ time_t get_pollT(){ return poll_interval;}
|
|||||||
*/
|
*/
|
||||||
sensordata_t *get_plugin(int N){
|
sensordata_t *get_plugin(int N){
|
||||||
if(N < 0 || N >= nplugins) return NULL;
|
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
|
// 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){
|
static void dumpsensors(struct sensordata_t* station){
|
||||||
//FNAME();
|
//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);
|
refresh_sensval(station);
|
||||||
#if 0
|
#if 0
|
||||||
DBG("New values...");
|
DBG("New values...");
|
||||||
@@ -124,12 +136,12 @@ int openplugins(char **paths, int N){
|
|||||||
char buf[PATH_MAX+1];
|
char buf[PATH_MAX+1];
|
||||||
if(!paths || !*paths || N < 1) return 0;
|
if(!paths || !*paths || N < 1) return 0;
|
||||||
if(allplugins || nplugins){
|
if(allplugins || nplugins){
|
||||||
WARNXL("Plugins already opened"); return 0;
|
LOGWARN("Plugins already opened"); return 0;
|
||||||
}
|
}
|
||||||
allplugins = MALLOC(sensordata_t*, N);
|
allplugins = MALLOC(sensordata_t*, N);
|
||||||
green("Try to open plugins:\n");
|
LOGMSG("Try to open plugins:");
|
||||||
for(int i = 0; i < N; ++i){
|
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]);
|
snprintf(buf, PATH_MAX, "%s", paths[i]);
|
||||||
char *colon = strchr(buf, ':');
|
char *colon = strchr(buf, ':');
|
||||||
if(colon) *colon++ = 0;
|
if(colon) *colon++ = 0;
|
||||||
@@ -145,10 +157,12 @@ int openplugins(char **paths, int N){
|
|||||||
S->tpoll = poll_interval;
|
S->tpoll = poll_interval;
|
||||||
allplugins[nplugins++] = S;
|
allplugins[nplugins++] = S;
|
||||||
int inited = sensinit(S); // here nplugins is index in array
|
int inited = sensinit(S); // here nplugins is index in array
|
||||||
if(!inited) WARNXL("Can't init plugin %s", paths[i]);
|
if(!inited){
|
||||||
else{
|
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");
|
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());
|
}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){
|
for(int i = 0; i < nplugins; ++i){
|
||||||
if(allplugins[i]->kill) allplugins[i]->kill(allplugins[i]);
|
if(allplugins[i]->kill) allplugins[i]->kill(allplugins[i]);
|
||||||
FREE(allplugins[i]);
|
FREE(allplugins[i]);
|
||||||
|
LOGWARN("Plugin %d killed", i);
|
||||||
}
|
}
|
||||||
FREE(allplugins);
|
FREE(allplugins);
|
||||||
nplugins = 0;
|
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
|
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]){
|
void get_fieldname(const val_t *v, char buf[KEY_LEN+1]){
|
||||||
if(!v || !buf) return;
|
if(!v || !buf) return;
|
||||||
int idx = v->meaning;
|
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
|
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
|
* @brief format_sensval - snprintf sensor's value into buffer
|
||||||
* @param v - value to get
|
* @param v - value to get
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ time_t get_pollT();
|
|||||||
|
|
||||||
double val2d(const val_t *v);
|
double val2d(const val_t *v);
|
||||||
void get_fieldname(const val_t *v, char buf[KEY_LEN+1]);
|
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_mute(sensordata_t *s);
|
||||||
int station_unmute(sensordata_t *s);
|
int station_unmute(sensordata_t *s);
|
||||||
|
|||||||
@@ -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)
|
#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
|
// show all connected libraries
|
||||||
static sl_sock_hresult_e listhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
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;
|
if(!client) return RESULT_FAIL;
|
||||||
char buf[SSZ_];
|
|
||||||
int N = get_nplugins();
|
int N = get_nplugins();
|
||||||
if(N < 1) return RESULT_FAIL;
|
if(N < 1) return RESULT_FAIL;
|
||||||
sensordata_t *d = NULL;
|
sensordata_t *d = NULL;
|
||||||
for(int i = 0; i < N; ++i){
|
for(int i = 0; i < N; ++i){
|
||||||
if(!(d = get_plugin(i))) continue;
|
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);
|
send_plugin_name(i, d, client);
|
||||||
else snprintf(buf, SSZ_, "PLUGIN[%d]=%s\nNVALUES[%d]=%d\n", i, d->name, i, d->Nvalues);
|
|
||||||
sl_sock_sendstrmessage(client, buf);
|
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
@@ -65,6 +71,7 @@ sensordata_t *get_plugin_w_message(sl_sock_t *client, int N){
|
|||||||
sl_sock_sendstrmessage(client, buf);
|
sl_sock_sendstrmessage(client, buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
send_plugin_name(N, s, client);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,16 +410,19 @@ int start_servers(const char *netnode, const char *sockpath){
|
|||||||
if(!s) continue;
|
if(!s) continue;
|
||||||
if(sensor_alive(s)) continue;
|
if(sensor_alive(s)) continue;
|
||||||
// sensor isn't inited - try to do it
|
// 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
|
s->kill(s); // clear resources
|
||||||
if(s->init){
|
if(s->init){
|
||||||
if(s->init(s)) LOGMSG("Sensor %s reinited @ %s", s->name, s->path);
|
if(s->init(s)){
|
||||||
else DBG("Can't reinit");
|
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);
|
while((tcur = time(NULL)) - tstart < WeatherConf.reinit_delay) sleep(1);
|
||||||
tstart = tcur;
|
tstart = tcur;
|
||||||
}
|
}
|
||||||
|
LOGERR("start_servers(): never reacheable point reached");
|
||||||
return TRUE; // should be never reached
|
return TRUE; // should be never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ sensordata_t *sensor_new(int N, const char *descr){
|
|||||||
s->get_value = common_getval;
|
s->get_value = common_getval;
|
||||||
s->kill = common_kill;
|
s->kill = common_kill;
|
||||||
s->PluginNo = N; // `init` shouldn't change this value
|
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);
|
pthread_mutex_init(&s->valmutex, NULL);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -51,8 +52,15 @@ sensordata_t *sensor_new(int N, const char *descr){
|
|||||||
* @return FALSE if thread is dead
|
* @return FALSE if thread is dead
|
||||||
*/
|
*/
|
||||||
int sensor_alive(sensordata_t *s){
|
int sensor_alive(sensordata_t *s){
|
||||||
if(!s || s->fdes < 0) return FALSE;
|
if(!s || s->fdes < 0){
|
||||||
if(pthread_kill(s->thread, 0)) return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +102,7 @@ void common_kill(sensordata_t *s){
|
|||||||
DBG("Delete RB");
|
DBG("Delete RB");
|
||||||
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
||||||
FREE(s->values);
|
FREE(s->values);
|
||||||
|
s->Nvalues = 0;
|
||||||
if(s->privdatafree) s->privdatafree(s->privdata);
|
if(s->privdatafree) s->privdatafree(s->privdata);
|
||||||
else FREE(s->privdata);
|
else FREE(s->privdata);
|
||||||
DBG("Sensor '%s' killed", s->name);
|
DBG("Sensor '%s' killed", s->name);
|
||||||
|
|||||||
Reference in New Issue
Block a user