mirror of
https://github.com/eddyem/small_tel.git
synced 2026-05-07 13:27:06 +03:00
add dead sensors' reinit, gathering all fresh data, fixed some little bugs
This commit is contained in:
@@ -49,6 +49,7 @@ static glob_pars defconf = {
|
|||||||
// only for config
|
// only for config
|
||||||
weather_conf_t WeatherConf = {
|
weather_conf_t WeatherConf = {
|
||||||
.ahtung_delay = 30*60, // 30 minutes
|
.ahtung_delay = 30*60, // 30 minutes
|
||||||
|
.reinit_delay = 60, // each 1 minute
|
||||||
.wind.good = 5., // < 5m/s - good weather
|
.wind.good = 5., // < 5m/s - good weather
|
||||||
.wind.bad = 10., // > 10m/s - bad weather
|
.wind.bad = 10., // > 10m/s - bad weather
|
||||||
.wind.terrible = 15., // > 15m/s - terrible weather
|
.wind.terrible = 15., // > 15m/s - terrible weather
|
||||||
@@ -92,9 +93,9 @@ sl_option_t cmdlnopts[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sl_option_t confopts[] = {
|
sl_option_t confopts[] = {
|
||||||
{"verbose", NEED_ARG, NULL, 'a', arg_int, APTR(&G.verb), "logfile verbocity level"},
|
{"verbose", NEED_ARG, NULL, 0, arg_int, APTR(&G.verb), "logfile verbocity level"},
|
||||||
{"ahtung_delay",NEED_ARG, NULL, 'b', arg_int, APTR(&WeatherConf.ahtung_delay), "delay in seconds after bad weather to change to good"},
|
{"ahtung_delay",NEED_ARG, NULL, 0, arg_int, APTR(&WeatherConf.ahtung_delay), "delay in seconds after bad weather to change to good"},
|
||||||
{"good_wind", NEED_ARG, NULL, 'c', arg_double, APTR(&WeatherConf.wind.good), "good wind while less this"},
|
{"good_wind", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.wind.good), "good wind while less this"},
|
||||||
{"bad_wind", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.wind.bad), "bad wind if more than this"},
|
{"bad_wind", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.wind.bad), "bad wind if more than this"},
|
||||||
{"terrible_wind",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.wind.terrible), "terrible wind if more than this"},
|
{"terrible_wind",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.wind.terrible), "terrible wind if more than this"},
|
||||||
{"good_humidity",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.humidity.good), "humidity is good until this"},
|
{"good_humidity",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.humidity.good), "humidity is good until this"},
|
||||||
@@ -107,6 +108,7 @@ sl_option_t confopts[] = {
|
|||||||
{"good_sky", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.good), "sky-ambient less than this is good"},
|
{"good_sky", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.good), "sky-ambient less than this is good"},
|
||||||
{"bad_sky", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.bad), "sky-ambient greater than this is bad"},
|
{"bad_sky", NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.bad), "sky-ambient greater than this is bad"},
|
||||||
{"terrible_sky",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.terrible), "sky-ambient greater than this is terrible"},
|
{"terrible_sky",NEED_ARG, NULL, 0, arg_double, APTR(&WeatherConf.sky.terrible), "sky-ambient greater than this is terrible"},
|
||||||
|
{"reinit_delay",NEED_ARG, NULL, 0, arg_int, APTR(&WeatherConf.reinit_delay), "delay (s) to reinit dead sensors"},
|
||||||
COMMON_OPTS
|
COMMON_OPTS
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ verbose = 2
|
|||||||
sockpath = "@weather"
|
sockpath = "@weather"
|
||||||
# sensors polling time - 1s
|
# sensors polling time - 1s
|
||||||
pollt = 1
|
pollt = 1
|
||||||
|
# try to reinit dead sensors each 10s
|
||||||
|
reinit_delay = 10
|
||||||
|
|
||||||
# !!! Point plugins in order of meaning: the most important are first !!!
|
# !!! Point plugins in order of meaning: the most important are first !!!
|
||||||
# see help for plugins format
|
# see help for plugins format
|
||||||
|
# this should be furst as almost a half of its sensors are broken
|
||||||
|
plugin = libreinhardt.so:D:/dev/ttyS0
|
||||||
plugin = libwxa100.so:D:/dev/pl2303_0
|
plugin = libwxa100.so:D:/dev/pl2303_0
|
||||||
plugin = libhydreon.so:D:/dev/ch340_0:1200
|
plugin = libhydreon.so:D:/dev/ch340_0:1200
|
||||||
plugin = libbtameteo.so
|
plugin = libbtameteo.so
|
||||||
# this should be last as almost a half of its sensors are broken
|
|
||||||
plugin = libreinhardt.so:D:/dev/ttyS0
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ int main(int argc, char **argv){
|
|||||||
sl_init();
|
sl_init();
|
||||||
GP = parse_args(argc, argv);
|
GP = parse_args(argc, argv);
|
||||||
if(!GP) ERRX("Error parsing args");
|
if(!GP) ERRX("Error parsing args");
|
||||||
|
sl_check4running((char*)__progname, GP->pidfile);
|
||||||
if(!GP->sockname) ERRX("Point command socket name");
|
if(!GP->sockname) ERRX("Point command socket name");
|
||||||
if(GP->logfile){
|
if(GP->logfile){
|
||||||
sl_loglevel_e lvl = LOGLEVEL_ERR + GP->verb;
|
sl_loglevel_e lvl = LOGLEVEL_ERR + GP->verb;
|
||||||
@@ -99,7 +100,6 @@ int main(int argc, char **argv){
|
|||||||
ERRX("Can't find any sensor plugin");
|
ERRX("Can't find any sensor plugin");
|
||||||
}
|
}
|
||||||
if(GP->nplugins && GP->nplugins != nopened) LOGWARN("Work without some plugins");
|
if(GP->nplugins && GP->nplugins != nopened) LOGWARN("Work without some plugins");
|
||||||
sl_check4running((char*)__progname, GP->pidfile);
|
|
||||||
#ifndef EBUG
|
#ifndef EBUG
|
||||||
sl_daemonize();
|
sl_daemonize();
|
||||||
while(1){ // guard for dead processes
|
while(1){ // guard for dead processes
|
||||||
@@ -121,7 +121,7 @@ int main(int argc, char **argv){
|
|||||||
signal(SIGUSR1, signals);
|
signal(SIGUSR1, signals);
|
||||||
signal(SIGUSR2, signals);
|
signal(SIGUSR2, signals);
|
||||||
if(!start_servers(GP->port, GP->sockname)) ERRX("Can't run server's threads");
|
if(!start_servers(GP->port, GP->sockname)) ERRX("Can't run server's threads");
|
||||||
while(1) pause();
|
//while(1) pause();
|
||||||
//WARNX("TEST ends");
|
//WARNX("TEST ends");
|
||||||
//signals(0);
|
//signals(0);
|
||||||
return 0; // never reached
|
return 0; // never reached
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ static val_t collected_data[NAMOUNT_OF_DATA] = {
|
|||||||
// {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER},
|
// {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// additional fields marked as `IS_OTHER` gathered from different stations
|
||||||
|
static int Nadditional = 0;
|
||||||
|
static val_t *additional_data = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief weather_level - set/clear weather level
|
* @brief weather_level - set/clear weather level
|
||||||
* @param newlvl - -1 for getter or 0..3 for setter
|
* @param newlvl - -1 for getter or 0..3 for setter
|
||||||
@@ -231,21 +235,22 @@ static double get_max_forT(sliding_max_t *sm, time_t tcutoff){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int collected_amount(){
|
int collected_amount(){
|
||||||
return NAMOUNT_OF_DATA;
|
return NAMOUNT_OF_DATA + Nadditional;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_collected(val_t *val, int N){
|
int get_collected(val_t *val, int N){
|
||||||
if(!val || N < 0 || N >= NAMOUNT_OF_DATA){
|
if(!val || N < 0 || N >= NAMOUNT_OF_DATA + Nadditional){
|
||||||
DBG("Wrong number (%d) requested or no place for data", N);
|
DBG("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];
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
char buf[KEY_LEN+1];
|
char buf[KEY_LEN+1];
|
||||||
get_fieldname(&collected_data[N], buf);
|
get_fieldname(dptr, buf);
|
||||||
DBG("Copied data of %d (u=%d, nm=%s)", N, collected_data[N].value.u, buf);
|
DBG("Copied data of %d (u=%d, nm=%s, t=%zd)", N, dptr->value.u, buf, dptr->time);
|
||||||
#endif
|
#endif
|
||||||
*val = collected_data[N];
|
*val = *dptr;
|
||||||
pthread_mutex_unlock(&datamutex);
|
pthread_mutex_unlock(&datamutex);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -318,6 +323,24 @@ static void fix_new_data(val_t *collected, const val_t *fresh, int force){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find value.name in `additional_data`, if need - allocate new memory and update
|
||||||
|
static void update_additional(val_t *value){
|
||||||
|
if(!value) return;
|
||||||
|
int idx = 0;
|
||||||
|
for(; idx < Nadditional; ++idx){
|
||||||
|
if(0 == strcmp(additional_data[idx].name, value->name)) break;
|
||||||
|
}
|
||||||
|
if(idx == Nadditional){ // not found -> allocate
|
||||||
|
additional_data = realloc(additional_data, sizeof(val_t) * (++Nadditional));
|
||||||
|
if(!additional_data){
|
||||||
|
LOGERR("update_additional() can't realloc()");
|
||||||
|
ERR("realloc()");
|
||||||
|
}
|
||||||
|
memcpy(&additional_data[idx], value, sizeof(val_t));
|
||||||
|
DBG("Allocated new field: %s", value->name);
|
||||||
|
}else fix_new_data(&additional_data[idx], value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief chkweatherlevel - increase weather level if need, also check force shutdown flags
|
* @brief chkweatherlevel - increase weather level if need, also check force shutdown flags
|
||||||
* @param curlevel - current max weather level
|
* @param curlevel - current max weather level
|
||||||
@@ -379,12 +402,14 @@ 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;
|
||||||
char reason[KEY_LEN+1] = {0}; // reason of weather level increasing
|
static char reason[KEY_LEN+1] = {0}; // reason of weather level increasing
|
||||||
val_t value;
|
val_t value;
|
||||||
if(!s || !s->get_value) return;
|
if(!s || !s->get_value) return;
|
||||||
//if(poll_time == 0) poll_time = get_pollT();
|
//if(poll_time == 0) poll_time = get_pollT();
|
||||||
uint32_t curlevel = 0; // this is worse weather leavel, start from best
|
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
|
||||||
time_t curtime = time(NULL);
|
time_t curtime = time(NULL);
|
||||||
|
time_t tpoll = get_pollT(), _3tpoll = 3*tpoll;
|
||||||
double dir = -100., dir2 = -100.; // mean wind directions
|
double dir = -100., dir2 = -100.; // mean wind directions
|
||||||
//DBG("%d meteo values", s->Nvalues);
|
//DBG("%d meteo values", s->Nvalues);
|
||||||
for(int i = 0; i < s->Nvalues; ++i){
|
for(int i = 0; i < s->Nvalues; ++i){
|
||||||
@@ -459,6 +484,10 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
break;
|
break;
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
|
if(value.meaning == IS_OTHER){ // check for new or existant field in `additional_data`
|
||||||
|
update_additional(&value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(idx < 0 || idx >= NAMOUNT_OF_DATA) continue;
|
if(idx < 0 || idx >= NAMOUNT_OF_DATA) continue;
|
||||||
//DBG("IDX=%d", idx);
|
//DBG("IDX=%d", idx);
|
||||||
pthread_mutex_lock(&datamutex);
|
pthread_mutex_lock(&datamutex);
|
||||||
@@ -489,13 +518,18 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
collected_data[NWINDDIR2].value.f = (float) dir2;
|
collected_data[NWINDDIR2].value.f = (float) dir2;
|
||||||
collected_data[NWINDDIR2].time = curtime;
|
collected_data[NWINDDIR2].time = curtime;
|
||||||
}
|
}
|
||||||
|
if(curtime - collected_data[NWIND].time < tpoll + 1){
|
||||||
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);
|
||||||
collected_data[NWINDMAX1].time = curtime;
|
collected_data[NWINDMAX1].time = curtime;
|
||||||
|
}
|
||||||
//DBG("check ahtung");
|
//DBG("check ahtung");
|
||||||
if(Forbidden) collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED;
|
time_t _2update = lasttupdate + _3tpoll;
|
||||||
else{
|
if(Forbidden){
|
||||||
|
collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED;
|
||||||
|
collected_data[NCOMMWEATH].time = curtime;
|
||||||
|
}else if(curtime >= _2update){ // need to update weather level
|
||||||
if(collected_data[NCOMMWEATH].value.u > curlevel){ // check timeout to make level lower
|
if(collected_data[NCOMMWEATH].value.u > curlevel){ // check timeout to make level lower
|
||||||
// DBG("curtime: %zd, curahtt: %d, diff: %zd, delay: %d", curtime, collected_data[NLASTAHTUNG].value.u, curtime - collected_data[NLASTAHTUNG].value.u, WeatherConf.ahtung_delay);
|
// DBG("curtime: %zd, curahtt: %d, diff: %zd, delay: %d", curtime, collected_data[NLASTAHTUNG].value.u, curtime - collected_data[NLASTAHTUNG].value.u, WeatherConf.ahtung_delay);
|
||||||
if(curtime - collected_data[NLASTAHTUNG].value.u > WeatherConf.ahtung_delay){
|
if(curtime - collected_data[NLASTAHTUNG].value.u > WeatherConf.ahtung_delay){
|
||||||
@@ -521,12 +555,14 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
}
|
}
|
||||||
if(curlevel){
|
if(curlevel){
|
||||||
collected_data[NLASTAHTUNG].value.u = curtime; // refresh last ahtung time only for level > good
|
collected_data[NLASTAHTUNG].value.u = curtime; // refresh last ahtung time only for level > good
|
||||||
|
collected_data[NLASTAHTUNG].time = curtime;
|
||||||
collected_data[NAHTUNGRSN].time = curtime;
|
collected_data[NAHTUNGRSN].time = curtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lasttupdate = curtime;
|
||||||
|
curlevel = 0; // wait for next collected max level
|
||||||
|
collected_data[NCOMMWEATH].time = curtime; // refresh `common weather` updating time
|
||||||
}
|
}
|
||||||
collected_data[NCOMMWEATH].time = curtime;
|
|
||||||
collected_data[NLASTAHTUNG].time = curtime;
|
|
||||||
pthread_mutex_unlock(&datamutex);
|
pthread_mutex_unlock(&datamutex);
|
||||||
//DBG("Refreshed");
|
//DBG("Refreshed");
|
||||||
}
|
}
|
||||||
@@ -546,25 +582,3 @@ void forbid_observations(int f){
|
|||||||
|
|
||||||
// `forbid` flag getter
|
// `forbid` flag getter
|
||||||
int is_forbidden(){ return Forbidden; }
|
int is_forbidden(){ return Forbidden; }
|
||||||
|
|
||||||
#if 0
|
|
||||||
// main cycle
|
|
||||||
void run_mainweather(){
|
|
||||||
int N = get_nplugins();
|
|
||||||
if(N < 1) return;
|
|
||||||
poll_time = get_pollT();
|
|
||||||
while(1){
|
|
||||||
int nactive = 0;
|
|
||||||
pthread_mutex_lock(&datamutex);
|
|
||||||
for(int i = N-1; i > -1; --i){ // the most important is the last
|
|
||||||
sensordata_t *s = get_plugin(i);
|
|
||||||
if(!s || !sensor_alive(s)) continue;
|
|
||||||
++nactive;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&datamutex);
|
|
||||||
if(nactive == 0) break; // no active sensors
|
|
||||||
usleep(10000);
|
|
||||||
}
|
|
||||||
LOGERR("Main weather collector died: all sensors lost");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ typedef struct{
|
|||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
int ahtung_delay; // delay to change "bad weather" to good after last "bad event"
|
int ahtung_delay; // delay to change "bad weather" to good after last "bad event"
|
||||||
|
int reinit_delay; // delay to check all sensors and reinit dead
|
||||||
// wind, m/s
|
// wind, m/s
|
||||||
weather_cond_t wind;
|
weather_cond_t wind;
|
||||||
// humidity, %%
|
// humidity, %%
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ static const val_t values[NAMOUNT] = {
|
|||||||
static void *mainthread(void *s){
|
static void *mainthread(void *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
sensordata_t *sensor = (sensordata_t *)s;
|
sensordata_t *sensor = (sensordata_t *)s;
|
||||||
while(1){
|
while(sensor->fdes > -1){
|
||||||
if(check_shm_block(&sdat)){
|
if(check_shm_block(&sdat)){
|
||||||
//DBG("Got next");
|
//DBG("Got next");
|
||||||
time_t tnow = time(NULL);
|
time_t tnow = time(NULL);
|
||||||
@@ -64,16 +64,13 @@ static void *mainthread(void *s){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, _U_ const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
sensordata_t *s = common_new();
|
if(!s) return FALSE;
|
||||||
if(!s) return NULL;
|
|
||||||
s->PluginNo = N;
|
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
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];
|
||||||
@@ -82,9 +79,9 @@ sensordata_t *sensor_new(int N, time_t pollt, _U_ const char *descr){
|
|||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
s->fdes = 0;
|
s->fdes = 0;
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ static void *mainthread(void *s){
|
|||||||
FNAME();
|
FNAME();
|
||||||
double t0 = sl_dtime();
|
double t0 = sl_dtime();
|
||||||
sensordata_t *sensor = (sensordata_t *)s;
|
sensordata_t *sensor = (sensordata_t *)s;
|
||||||
while(1){
|
while(sensor->fdes > -1){
|
||||||
//DBG("locked");
|
//DBG("locked");
|
||||||
pthread_mutex_lock(&sensor->valmutex);
|
pthread_mutex_lock(&sensor->valmutex);
|
||||||
float f = sensor->values[0].value.f + (drand48() - 0.5) / 2.;
|
float f = sensor->values[0].value.f + (drand48() - 0.5) / 2.;
|
||||||
@@ -69,13 +69,11 @@ static void *mainthread(void *s){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, _U_ const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
sensordata_t *s = common_new();
|
if(!s) return FALSE;
|
||||||
if(!s) return NULL;
|
|
||||||
s->Nvalues = NS;
|
s->Nvalues = NS;
|
||||||
strncpy(s->name, SENSOR_NAME, NAME_LEN);
|
strncpy(s->name, SENSOR_NAME, NAME_LEN);
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
s->values = MALLOC(val_t, NS);
|
s->values = MALLOC(val_t, NS);
|
||||||
for(int i = 0; i < NS; ++i) s->values[i] = values[i];
|
for(int i = 0; i < NS; ++i) s->values[i] = values[i];
|
||||||
s->values[0].value.f = 1.;
|
s->values[0].value.f = 1.;
|
||||||
@@ -85,11 +83,10 @@ sensordata_t *sensor_new(int N, time_t pollt, _U_ const char *descr){
|
|||||||
s->values[4].value.f = 89.;
|
s->values[4].value.f = 89.;
|
||||||
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;
|
||||||
s->PluginNo = N;
|
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
s->fdes = 0;
|
s->fdes = 0;
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,28 +120,24 @@ static void *mainthread(void *s){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s) return FALSE;
|
||||||
int fd = getFD(descr);
|
int fd = getFD(s->path);
|
||||||
if(fd < 0) return NULL;
|
if(fd < 0) return FALSE;
|
||||||
sensordata_t *s = common_new();
|
|
||||||
if(!s) return NULL;
|
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
s->PluginNo = N;
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
|
||||||
s->values = MALLOC(val_t, NS);
|
s->values = MALLOC(val_t, NS);
|
||||||
// don't use memcpy, as `values` could be aligned
|
// don't use memcpy, as `values` could be aligned
|
||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,25 +194,21 @@ static void *mainthread(void *s){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s) return FALSE;
|
||||||
int fd = getFD(descr);
|
int fd = getFD(s->path);
|
||||||
if(fd < 0) return NULL;
|
if(fd < 0) return FALSE;
|
||||||
sensordata_t *s = common_new();
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
if(!s) return NULL;
|
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
s->PluginNo = N;
|
|
||||||
s->Nvalues = NAMOUNT;
|
s->Nvalues = NAMOUNT;
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
s->values = MALLOC(val_t, NAMOUNT);
|
s->values = MALLOC(val_t, NAMOUNT);
|
||||||
// don't use memcpy, as `values` could be aligned
|
// don't use memcpy, as `values` could be aligned
|
||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ static void *mainthread(void *s){
|
|||||||
time_t tnow = time(NULL);
|
time_t tnow = time(NULL);
|
||||||
if(tnow - tpoll > sensor->tpoll){
|
if(tnow - tpoll > sensor->tpoll){
|
||||||
int dlen = sprintf(buf, "%s0\n%s1\n", commands[CMD_DISTANCE], commands[CMD_DISTANCE]);
|
int dlen = sprintf(buf, "%s0\n%s1\n", commands[CMD_DISTANCE], commands[CMD_DISTANCE]);
|
||||||
if(sl_tty_write(sensor->fdes, buf, dlen)){
|
if(dlen != write(sensor->fdes, buf, dlen)){
|
||||||
WARN("Can't ask new data");
|
WARN("Can't ask new data from lightning monitor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll);
|
DBG("poll @%zd, pollt=%zd", tnow, sensor->tpoll);
|
||||||
@@ -169,22 +169,24 @@ static void *mainthread(void *s){
|
|||||||
sensor->values[NLIGHTNING].time = tnow;
|
sensor->values[NLIGHTNING].time = tnow;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&sensor->valmutex);
|
pthread_mutex_unlock(&sensor->valmutex);
|
||||||
if(gotfresh && sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
if(gotfresh) DBG("got fresh data");
|
||||||
|
if(gotfresh && sensor->freshdatahandler){
|
||||||
|
DBG("Run fresh data handler");
|
||||||
|
sensor->freshdatahandler(sensor);
|
||||||
|
}
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
DBG("suicide");
|
||||||
sensor->kill(sensor);
|
sensor->kill(sensor);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t _U_ pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s) return FALSE;
|
||||||
int fd = getFD(descr);
|
int fd = getFD(s->path);
|
||||||
if(fd < 0) return NULL;
|
if(fd < 0) return FALSE;
|
||||||
sensordata_t *s = common_new();
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
if(!s) return NULL;
|
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
|
||||||
s->PluginNo = N;
|
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
s->Nvalues = NAMOUNT;
|
s->Nvalues = NAMOUNT;
|
||||||
s->tpoll = TCHECK;
|
s->tpoll = TCHECK;
|
||||||
@@ -193,7 +195,7 @@ sensordata_t *sensor_new(int N, time_t _U_ pollt, const char *descr){
|
|||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static void *mainthread(void *s){
|
|||||||
while(sensor->fdes > -1){
|
while(sensor->fdes > -1){
|
||||||
time_t tnow = time(NULL);
|
time_t tnow = time(NULL);
|
||||||
if(tnow - tpoll > sensor->tpoll){
|
if(tnow - tpoll > sensor->tpoll){
|
||||||
if(sl_tty_write(sensor->fdes, "?U\r\n", 4)){
|
if(4 != write(sensor->fdes, "?U\r\n", 4)){
|
||||||
WARN("Can't ask new data");
|
WARN("Can't ask new data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -166,24 +166,20 @@ static void *mainthread(void *s){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s) return FALSE;
|
||||||
int fd = getFD(descr);
|
int fd = getFD(s->path);
|
||||||
if(fd < 0) return NULL;
|
if(fd < 0) return FALSE;
|
||||||
sensordata_t *s = common_new();
|
|
||||||
if(!s) return NULL;
|
|
||||||
s->Nvalues = NAMOUNT;
|
s->Nvalues = NAMOUNT;
|
||||||
s->PluginNo = N;
|
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
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];
|
||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ enum{
|
|||||||
static netsnmp_session *snmp_session;
|
static netsnmp_session *snmp_session;
|
||||||
static oid anOID[OID_AMOUNT][MAX_OID_LEN];
|
static oid anOID[OID_AMOUNT][MAX_OID_LEN];
|
||||||
static size_t anOID_len[OID_AMOUNT];
|
static size_t anOID_len[OID_AMOUNT];
|
||||||
static int running = 1;
|
|
||||||
|
|
||||||
const char *oids[OID_AMOUNT] = {
|
const char *oids[OID_AMOUNT] = {
|
||||||
[OID_BATT_STATUS] = ".1.3.6.1.2.1.33.1.2.1.0",
|
[OID_BATT_STATUS] = ".1.3.6.1.2.1.33.1.2.1.0",
|
||||||
@@ -114,7 +113,7 @@ static void *mainthread(void *s){
|
|||||||
double t0 = sl_dtime();
|
double t0 = sl_dtime();
|
||||||
sensordata_t *sensor = (sensordata_t *)s;
|
sensordata_t *sensor = (sensordata_t *)s;
|
||||||
netsnmp_pdu *pdu, *response;
|
netsnmp_pdu *pdu, *response;
|
||||||
while(running){
|
while(sensor->fdes > -1){
|
||||||
//DBG("run");
|
//DBG("run");
|
||||||
pdu = snmp_pdu_create(SNMP_MSG_GET);
|
pdu = snmp_pdu_create(SNMP_MSG_GET);
|
||||||
for(int i = 0; i < OID_AMOUNT; ++i)
|
for(int i = 0; i < OID_AMOUNT; ++i)
|
||||||
@@ -123,19 +122,20 @@ static void *mainthread(void *s){
|
|||||||
//DBG("status = %d", status);
|
//DBG("status = %d", status);
|
||||||
if(status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR){
|
if(status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR){
|
||||||
time_t curt = time(NULL);
|
time_t curt = time(NULL);
|
||||||
netsnmp_variable_list *vars = response->variables;
|
netsnmp_variable_list *vars = response->variables; // OID_BATT_STATUS
|
||||||
pthread_mutex_lock(&sensor->valmutex);
|
pthread_mutex_lock(&sensor->valmutex);
|
||||||
int ival = *vars->val.integer;
|
int ival = *vars->val.integer;
|
||||||
if(ival > 0 && ival < BATT_STAT_AMOUNT)
|
if(ival > 0 && ival < BATT_STAT_AMOUNT){
|
||||||
snprintf(sensor->values[NBATSTAT].value.str, STRT_LEN+1, "%s", batt_stat[ival]);
|
snprintf(sensor->values[NBATSTAT].value.str, STRT_LEN+1, "%s", batt_stat[ival]);
|
||||||
vars = vars->next_variable;
|
}
|
||||||
|
vars = vars->next_variable; // OID_BATT_SECONDS_ONBAT
|
||||||
uint32_t tonbat = (uint32_t) *vars->val.integer;
|
uint32_t tonbat = (uint32_t) *vars->val.integer;
|
||||||
sensor->values[NTONBAT].value.u = tonbat;
|
sensor->values[NTONBAT].value.u = tonbat;
|
||||||
vars = vars->next_variable;
|
vars = vars->next_variable; // OID_BATT_EST_MINUTES
|
||||||
sensor->values[NTREMAIN].value.u = 60 * (uint32_t) *vars->val.integer;
|
sensor->values[NTREMAIN].value.u = 60 * (uint32_t) *vars->val.integer;
|
||||||
vars = vars->next_variable;
|
vars = vars->next_variable; // OID_BATT_CAPACITY
|
||||||
sensor->values[NBATCAP].value.u = (uint32_t) *vars->val.integer;
|
sensor->values[NBATCAP].value.u = (uint32_t) *vars->val.integer;
|
||||||
vars = vars->next_variable;
|
vars = vars->next_variable; // OID_OUTPUT_SOURCE
|
||||||
ival = *vars->val.integer;
|
ival = *vars->val.integer;
|
||||||
if(ival > 0 && ival < SOURCE_AMOUNT)
|
if(ival > 0 && ival < SOURCE_AMOUNT)
|
||||||
snprintf(sensor->values[NSOURCE].value.str, STRT_LEN+1, "%s", sources[ival]);
|
snprintf(sensor->values[NSOURCE].value.str, STRT_LEN+1, "%s", sources[ival]);
|
||||||
@@ -144,6 +144,7 @@ static void *mainthread(void *s){
|
|||||||
}else sensor->values[NONBAT].value.u = 0;
|
}else sensor->values[NONBAT].value.u = 0;
|
||||||
for(int i = 0; i < NAMOUNT; ++i)
|
for(int i = 0; i < NAMOUNT; ++i)
|
||||||
sensor->values[i].time = curt;
|
sensor->values[i].time = curt;
|
||||||
|
//DBG("times updated to %zd", curt);
|
||||||
pthread_mutex_unlock(&sensor->valmutex);
|
pthread_mutex_unlock(&sensor->valmutex);
|
||||||
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
||||||
}else DBG("Error in packet");
|
}else DBG("Error in packet");
|
||||||
@@ -156,15 +157,15 @@ static void *mainthread(void *s){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void snmp_kill(sensordata_t *s){
|
static void snmp_kill(sensordata_t *s){
|
||||||
running = 0;
|
s->fdes = -1;
|
||||||
pthread_join(s->thread, NULL);
|
pthread_join(s->thread, NULL);
|
||||||
snmp_close(snmp_session);
|
snmp_close(snmp_session);
|
||||||
common_kill(s);
|
common_kill(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s || !s->path[0]) return FALSE;
|
||||||
|
|
||||||
netsnmp_session session;
|
netsnmp_session session;
|
||||||
init_snmp("snmpapp");
|
init_snmp("snmpapp");
|
||||||
@@ -174,29 +175,24 @@ sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
|||||||
session.community = (u_char *)"public";
|
session.community = (u_char *)"public";
|
||||||
session.community_len = strlen((const char *)session.community);
|
session.community_len = strlen((const char *)session.community);
|
||||||
|
|
||||||
const char *colon = strchr(descr, ':');
|
DBG("PATH: %s", s->path);
|
||||||
if(colon) descr = colon + 1; // omit "N:" in field "N:host"
|
|
||||||
session.peername = strdup(descr);
|
const char *colon = strchr(s->path, ':');
|
||||||
|
if(colon) ++colon; // omit "N:" in field "N:host"
|
||||||
|
session.peername = strdup(colon);
|
||||||
|
|
||||||
snmp_session = snmp_open(&session);
|
snmp_session = snmp_open(&session);
|
||||||
if(!snmp_session){
|
if(!snmp_session){
|
||||||
snmp_sess_perror("snmp_open", &session);
|
snmp_sess_perror("snmp_open", &session);
|
||||||
FREE(session.peername);
|
FREE(session.peername);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *s = common_new();
|
|
||||||
if(!s){
|
|
||||||
snmp_close(snmp_session);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
s->kill = snmp_kill;
|
s->kill = snmp_kill;
|
||||||
|
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
s->PluginNo = N;
|
s->fdes = 0;
|
||||||
s->fdes = -1;
|
|
||||||
s->Nvalues = NAMOUNT;
|
s->Nvalues = NAMOUNT;
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
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];
|
||||||
|
|
||||||
@@ -214,7 +210,7 @@ sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
|||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ static void *mainthread(void *s){
|
|||||||
while(sensor->fdes > -1){
|
while(sensor->fdes > -1){
|
||||||
time_t tnow = time(NULL);
|
time_t tnow = time(NULL);
|
||||||
if(tnow - tpoll > sensor->tpoll){
|
if(tnow - tpoll > sensor->tpoll){
|
||||||
if(sl_tty_write(sensor->fdes, "!0R0\r\n", 6)){
|
if(6 != write(sensor->fdes, "!0R0\r\n", 6)){
|
||||||
WARN("Can't ask new data");
|
WARN("Can't ask new data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -194,25 +194,21 @@ static void *mainthread(void *s){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensordata_t *sensor_new(int N, time_t pollt, const char *descr){
|
int sensor_init(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!descr || !*descr) return NULL;
|
if(!s) return FALSE;
|
||||||
int fd = getFD(descr);
|
int fd = getFD(s->path);
|
||||||
if(fd < 0) return NULL;
|
if(fd < 0) return FALSE;
|
||||||
sensordata_t *s = common_new();
|
snprintf(s->name, NAME_LEN, "%s", SENSOR_NAME);
|
||||||
if(!s) return NULL;
|
|
||||||
snprintf(s->name, NAME_LEN, "%s @ %s", SENSOR_NAME, descr);
|
|
||||||
s->PluginNo = N;
|
|
||||||
s->fdes = fd;
|
s->fdes = fd;
|
||||||
s->Nvalues = NAMOUNT;
|
s->Nvalues = NAMOUNT;
|
||||||
if(pollt) s->tpoll = pollt;
|
|
||||||
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];
|
||||||
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);
|
s->kill(s);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return s;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void *open_plugin(const char *name){
|
|||||||
*/
|
*/
|
||||||
static void dumpsensors(struct sensordata_t* station){
|
static void dumpsensors(struct sensordata_t* station){
|
||||||
//FNAME();
|
//FNAME();
|
||||||
if(!station || !station->get_value || station->Nvalues < 1 || station->IsMuted) return;
|
if(!sensor_alive(station) || !station->get_value || station->Nvalues < 1 || station->IsMuted) return;
|
||||||
refresh_sensval(station);
|
refresh_sensval(station);
|
||||||
#if 0
|
#if 0
|
||||||
DBG("New values...");
|
DBG("New values...");
|
||||||
@@ -136,14 +136,20 @@ int openplugins(char **paths, int N){
|
|||||||
void* dlh = open_plugin(buf);
|
void* dlh = open_plugin(buf);
|
||||||
if(!dlh) continue;
|
if(!dlh) continue;
|
||||||
DBG("OPENED");
|
DBG("OPENED");
|
||||||
sensor_new_t sensnew = (sensor_new_t) dlsym(dlh, "sensor_new");
|
sensor_init_t sensinit = (sensor_init_t) dlsym(dlh, "sensor_init");
|
||||||
if(sensnew){
|
if(sensinit){
|
||||||
sensordata_t *S = sensnew(nplugins, poll_interval, colon); // here nplugins is index in array
|
sensordata_t *S = sensor_new(nplugins, colon);
|
||||||
if(!S) WARNXL("Can't init plugin %s", paths[i]);
|
if(!S) WARNXL("Can't allocate memory for 'sensor' structure");
|
||||||
|
else{
|
||||||
|
S->init = sensinit;
|
||||||
|
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{
|
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);
|
LOGMSG("Plugin %s nave %d sensors", paths[i], S->Nvalues);
|
||||||
allplugins[nplugins++] = S;
|
}
|
||||||
}
|
}
|
||||||
}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());
|
||||||
}
|
}
|
||||||
@@ -158,6 +164,7 @@ void closeplugins(){
|
|||||||
if(!allplugins || nplugins < 1) return;
|
if(!allplugins || nplugins < 1) return;
|
||||||
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);
|
FREE(allplugins);
|
||||||
nplugins = 0;
|
nplugins = 0;
|
||||||
|
|||||||
@@ -39,16 +39,18 @@ static sl_sock_hresult_e timehandler(sl_sock_t *client, _U_ sl_sock_hitem_t *ite
|
|||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SSZ_ (PATH_MAX + 256)
|
||||||
// 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[256];
|
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;
|
||||||
snprintf(buf, 255, "PLUGIN[%d]=%s\nNVALUES[%d]=%d\n", i, d->name, i, d->Nvalues);
|
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);
|
sl_sock_sendstrmessage(client, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -83,7 +85,7 @@ static void showdata(sl_sock_t *client, int N){
|
|||||||
if(!s) return;
|
if(!s) return;
|
||||||
Ncoll = s->Nvalues;
|
Ncoll = s->Nvalues;
|
||||||
}
|
}
|
||||||
time_t oldest = time(NULL) - WeatherConf.ahtung_delay, mstm = 0;
|
time_t oldest = time(NULL) - 2 * WeatherConf.ahtung_delay, mstm = 0;
|
||||||
|
|
||||||
for(int i = 0; i < Ncoll; ++i){
|
for(int i = 0; i < Ncoll; ++i){
|
||||||
int ans = 0;
|
int ans = 0;
|
||||||
@@ -402,7 +404,25 @@ int start_servers(const char *netnode, const char *sockpath){
|
|||||||
sl_sock_dischandler(localsocket, disconnected);
|
sl_sock_dischandler(localsocket, disconnected);
|
||||||
sl_sock_defmsghandler(netsocket, defhandler);
|
sl_sock_defmsghandler(netsocket, defhandler);
|
||||||
sl_sock_defmsghandler(localsocket, defhandler);
|
sl_sock_defmsghandler(localsocket, defhandler);
|
||||||
return TRUE;
|
// now run checking cycle
|
||||||
|
int Nplugins = get_nplugins();
|
||||||
|
time_t tstart = time(NULL), tcur;
|
||||||
|
while(1){
|
||||||
|
for(int i = 0; i < Nplugins; ++i){
|
||||||
|
sensordata_t *s = get_plugin(i);
|
||||||
|
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);
|
||||||
|
if(s->init){
|
||||||
|
if(s->init(s)) LOGMSG("Sensor %s reinited @ %s", s->name, s->path);
|
||||||
|
else DBG("Can't reinit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while((tcur = time(NULL)) - tstart < WeatherConf.reinit_delay) sleep(1);
|
||||||
|
tstart = tcur;
|
||||||
|
}
|
||||||
|
return TRUE; // should be never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
void kill_servers(){
|
void kill_servers(){
|
||||||
|
|||||||
@@ -29,15 +29,18 @@
|
|||||||
//static int common_init(sensordata_t*, int, time_t, int);
|
//static int common_init(sensordata_t*, int, time_t, int);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief common_new - call this function from your plugin's `sensor_new`
|
* @brief sensor_new - call this function before calling `sensor_init`
|
||||||
* @return
|
* @param N - plugin number in array
|
||||||
|
* @return pointer to allocated sensor's structure
|
||||||
*/
|
*/
|
||||||
sensordata_t *common_new(){
|
sensordata_t *sensor_new(int N, const char *descr){
|
||||||
sensordata_t *s = MALLOC(sensordata_t, 1);
|
sensordata_t *s = MALLOC(sensordata_t, 1);
|
||||||
s->fdes = -1; // not inited
|
s->fdes = -1; // not inited
|
||||||
s->onrefresh = common_onrefresh;
|
s->onrefresh = common_onrefresh; // `init` function can redefine basic stubs
|
||||||
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
|
||||||
|
snprintf(s->path, PATH_MAX, "%s", descr); // `init` shouldn't change this value
|
||||||
pthread_mutex_init(&s->valmutex, NULL);
|
pthread_mutex_init(&s->valmutex, NULL);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -66,19 +69,26 @@ int common_onrefresh(sensordata_t *s, void (*handler)(sensordata_t *)){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief common_kill - common `die` function
|
* @brief common_kill - common `die` function (close, but don't destroy sensor)
|
||||||
* @param s - sensor
|
* @param s - sensor
|
||||||
*/
|
*/
|
||||||
void common_kill(sensordata_t *s){
|
void common_kill(sensordata_t *s){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!s) return;
|
if(!s) return;
|
||||||
if(s->fdes > -1){ // inited and maybe have opened file/socket
|
if(s->fdes > -1){ // inited and maybe have opened file/socket
|
||||||
|
if(pthread_equal(pthread_self(), s->thread)){
|
||||||
|
DBG("Don't cancel myself");
|
||||||
|
}else{
|
||||||
|
DBG("Cancel sensor's thread");
|
||||||
if(0 == pthread_cancel(s->thread)){
|
if(0 == pthread_cancel(s->thread)){
|
||||||
DBG("%s main thread canceled, join", s->name);
|
DBG("%s main thread canceled, join", s->name);
|
||||||
pthread_join(s->thread, NULL);
|
pthread_join(s->thread, NULL);
|
||||||
DBG("Done");
|
DBG("Done");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
close(s->fdes);
|
close(s->fdes);
|
||||||
|
s->fdes = -1;
|
||||||
|
DBG("FD closed");
|
||||||
}
|
}
|
||||||
DBG("Delete RB");
|
DBG("Delete RB");
|
||||||
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
||||||
@@ -86,9 +96,8 @@ void common_kill(sensordata_t *s){
|
|||||||
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);
|
||||||
LOGERR("Sensor '%s' killed", s->name);
|
if(s->path[0]) LOGERR("Sensor '%s' @ '%s' killed", s->name, s->path);
|
||||||
FREE(s);
|
else LOGERR("Sensor '%s' killed", s->name);
|
||||||
DBG("There's no more this sensor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -97,10 +97,12 @@ typedef struct{
|
|||||||
// all sensor's data
|
// all sensor's data
|
||||||
// all functions have `this` as first arg
|
// all functions have `this` as first arg
|
||||||
typedef struct sensordata_t{
|
typedef struct sensordata_t{
|
||||||
char name[NAME_LEN+1]; // max 31 symbol of sensor's name (e.g. "rain sensor")
|
char name[NAME_LEN+1]; // sensor's name (e.g. "rain sensor @ localhost")
|
||||||
|
char path[PATH_MAX]; // path to sensor's device or socket description in format D:/path, U:path, N:host:port
|
||||||
int Nvalues; // amount of values
|
int Nvalues; // amount of values
|
||||||
int PluginNo; // plugin number in array (if several)
|
int PluginNo; // plugin number in array (if several)
|
||||||
int IsMuted; // ==1 for "muted" station (don't refresh sensors' data)
|
int IsMuted; // ==1 for "muted" station (don't refresh sensors' data)
|
||||||
|
int (*init)(struct sensordata_t*); // main init function
|
||||||
int (*onrefresh)(struct sensordata_t*, void (*handler)(struct sensordata_t*)); // handler of new data; return TRUE if OK
|
int (*onrefresh)(struct sensordata_t*, void (*handler)(struct sensordata_t*)); // handler of new data; return TRUE if OK
|
||||||
int (*get_value)(struct sensordata_t*, val_t*, int); // getter of Nth value
|
int (*get_value)(struct sensordata_t*, val_t*, int); // getter of Nth value
|
||||||
void (*kill)(struct sensordata_t*); // close everything and remove sensor
|
void (*kill)(struct sensordata_t*); // close everything and remove sensor
|
||||||
@@ -118,14 +120,14 @@ typedef struct sensordata_t{
|
|||||||
} sensordata_t;
|
} sensordata_t;
|
||||||
|
|
||||||
// type for function extraction
|
// type for function extraction
|
||||||
typedef sensordata_t* (*sensor_new_t)(int, time_t, const char*);
|
typedef int (*sensor_init_t)(sensordata_t *);
|
||||||
|
|
||||||
// init meteostation with given PluginNo, poll_interval and descriptor
|
// init meteostation with given PluginNo, poll_interval and descriptor
|
||||||
sensordata_t *sensor_new(int PluginNo, time_t poll_interval, const char *descr); // external initial function for any plugin
|
//sensordata_t *sensor_init(int PluginNo, time_t poll_interval, const char *descr); // external initial function for any plugin
|
||||||
int sensor_alive(sensordata_t *s);
|
int sensor_alive(sensordata_t *s);
|
||||||
|
sensordata_t *sensor_new(int N, const char *descr);
|
||||||
|
|
||||||
// private function (for plugins usage only)
|
// private function (for plugins usage only)
|
||||||
sensordata_t *common_new();
|
|
||||||
void common_kill(sensordata_t *s);
|
void common_kill(sensordata_t *s);
|
||||||
int common_onrefresh(sensordata_t *s, void (*handler)(sensordata_t *));
|
int common_onrefresh(sensordata_t *s, void (*handler)(sensordata_t *));
|
||||||
int common_getval(struct sensordata_t *s, val_t *o, int N);
|
int common_getval(struct sensordata_t *s, val_t *o, int N);
|
||||||
|
|||||||
Reference in New Issue
Block a user