From 05e57ef012061a7855fd17e034cebfe0b04a9b72 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Wed, 29 Apr 2026 17:47:23 +0300 Subject: [PATCH] .. --- .../weatherdaemon_multimeteo/CMakeLists.txt | 2 +- Daemons/weatherdaemon_multimeteo/cmdlnopts.c | 4 + Daemons/weatherdaemon_multimeteo/fd.c | 3 + Daemons/weatherdaemon_multimeteo/main.c | 6 +- .../weatherdaemon_multimeteo/mainweather.c | 170 +++++++++++++----- .../weatherdaemon_multimeteo/mainweather.h | 5 + .../weatherdaemon_multimeteo/plugins/dummy.c | 6 +- Daemons/weatherdaemon_multimeteo/sensors.c | 11 ++ Daemons/weatherdaemon_multimeteo/sensors.h | 1 + Daemons/weatherdaemon_multimeteo/server.c | 89 ++++----- 10 files changed, 203 insertions(+), 94 deletions(-) diff --git a/Daemons/weatherdaemon_multimeteo/CMakeLists.txt b/Daemons/weatherdaemon_multimeteo/CMakeLists.txt index 333a1d7..fa66b05 100644 --- a/Daemons/weatherdaemon_multimeteo/CMakeLists.txt +++ b/Daemons/weatherdaemon_multimeteo/CMakeLists.txt @@ -27,7 +27,7 @@ message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") add_definitions(-D_XOPEN_SOURCE=1234 -D_DEFAULT_SOURCE -D_GNU_SOURCE -DPACKAGE_VERSION=\"${VERSION}\" -DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\" - -DMAJOR_VERSION=\"${MAJOR_VESION}\") + -DMAJOR_VERSION=\"${MAJOR_VERSION}\") set(CMAKE_COLOR_MAKEFILE ON) diff --git a/Daemons/weatherdaemon_multimeteo/cmdlnopts.c b/Daemons/weatherdaemon_multimeteo/cmdlnopts.c index e24d036..4d979ca 100644 --- a/Daemons/weatherdaemon_multimeteo/cmdlnopts.c +++ b/Daemons/weatherdaemon_multimeteo/cmdlnopts.c @@ -143,7 +143,9 @@ static void compplugins(glob_pars *cmdline, glob_pars *conf){ } // don't sort: we need leave priority as user pointed //qsort(newarray, newsize, sizeof(char*), sortstrings); +#ifdef EBUG DBG("NOW together:"); p = newarray; while(*p) printf("\t%s\n", *p++); +#endif for(int i = 0; i < newsize-1; ++i){ if(NULL == newarray[i]) continue; for(int j = i+1; j < newsize; ++j){ @@ -177,7 +179,9 @@ static void compplugins(glob_pars *cmdline, glob_pars *conf){ i = j; } #endif +#ifdef EBUG DBG("Result:"); p = newarray; while(*p) printf("\t%s\n", *p++); +#endif cmdline->plugins = newarray; cmdline->nplugins = nondoubleidx; } diff --git a/Daemons/weatherdaemon_multimeteo/fd.c b/Daemons/weatherdaemon_multimeteo/fd.c index 33f9105..3fa3908 100644 --- a/Daemons/weatherdaemon_multimeteo/fd.c +++ b/Daemons/weatherdaemon_multimeteo/fd.c @@ -96,6 +96,7 @@ static int opensocket(char *path, sl_socktype_e type){ memcpy(unaddr.sun_path, str, 106); FREE(str); ai.ai_family = AF_UNIX; + // TODO: add `socket` and `connect` } break; case SOCKT_NET: @@ -121,6 +122,7 @@ static int opensocket(char *path, sl_socktype_e type){ close(sock); sock = -1; } else break; } + freeaddrinfo(res); break; default: // never reached WARNX("Unsupported socket type %d", type); @@ -141,6 +143,7 @@ int getFD(char *path){ char type = *path; if(path[1] != ':') return -1; // after protocol letter should be delimeter path += 2; + if(!*path) return -1; // empty path switch(type){ case 'D': // serial device return openserial(path); diff --git a/Daemons/weatherdaemon_multimeteo/main.c b/Daemons/weatherdaemon_multimeteo/main.c index c985cdd..b0ce7b2 100644 --- a/Daemons/weatherdaemon_multimeteo/main.c +++ b/Daemons/weatherdaemon_multimeteo/main.c @@ -40,12 +40,12 @@ void signals(int signo){ LOGDBG("Child gotta signal %d", signo); if(signo == SIGUSR1){ forbid_observations(1); - LOGMSG("Got signal `observations forbidden`"); + LOGWARN("Got signal `observations forbidden`, set FORBIDDEN"); signal(signo, signals); return; }else if(signo == SIGUSR2){ forbid_observations(0); - LOGMSG("Got signal `observations permitted`"); + LOGWARN("Got signal `observations permitted`, clear FORBIDDEN"); signal(signo, signals); return; } @@ -121,7 +121,7 @@ int main(int argc, char **argv){ signal(SIGUSR1, signals); signal(SIGUSR2, signals); if(!start_servers(GP->port, GP->sockname)) ERRX("Can't run server's threads"); - while(1); + while(1) pause(); //WARNX("TEST ends"); //signals(0); return 0; // never reached diff --git a/Daemons/weatherdaemon_multimeteo/mainweather.c b/Daemons/weatherdaemon_multimeteo/mainweather.c index 40894f4..d82bd85 100644 --- a/Daemons/weatherdaemon_multimeteo/mainweather.c +++ b/Daemons/weatherdaemon_multimeteo/mainweather.c @@ -77,18 +77,68 @@ static val_t collected_data[NAMOUNT_OF_DATA] = { [NMIST] = {.sense = VAL_BROKEN, .type = VALT_UINT, .meaning = IS_MIST}, [NCLOUDS] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_CLOUDS}, [NSKYTEMP] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_SKYTEMP}, + [NLIGHTDIST] = {.sense = VAL_FORCEDSHTDN, .type = VALT_FLOAT, .meaning = IS_LIGTDIST}, // these are calculated values [NCOMMWEATH] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "WEATHER", .comment = "Weather (0..3: good/bad/terrible/prohibited)"}, [NLASTAHTUNG] = {.sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "EVTTIME", .comment = "UNIX-time of last weather level changing"}, [NAHTUNGRSN] = {.sense = VAL_RECOMMENDED, .type = VALT_STRING, .meaning = IS_OTHER, .name = "EVTRSN", .comment = "Last weather level increasing reason"}, - [NLIGHTDIST] = {.sense = VAL_FORCEDSHTDN, .type = VALT_FLOAT, .meaning = IS_LIGTDIST}, // virtual values for weather level / flags changing [NBADWEATH] = {.sense = VAL_BROKEN, .type = VALT_UINT, .meaning = IS_BADWEATH, .name = "BADWEATH", .comment = "Flag changing weather level to 'BAD'"}, [NTERRWEATH] = {.sense = VAL_BROKEN, .type = VALT_UINT, .meaning = IS_TERRIBLEWEATH, .name = "TERWEATH", .comment = "Flag changing weather level to 'TERRIBLE'"}, - [NFORCEDSHTDN] = {.sense = VAL_FORCEDSHTDN, .type = VALT_UINT, .meaning = IS_FORCEDSHTDN, .name = "FORCEOFF", .comment = "Station should be powered off NOW"}, + [NFORCEDSHTDN] = {.sense = VAL_FORCEDSHTDN, .type = VALT_UINT, .meaning = IS_FORCEDSHTDN, .name = "FORCEOFF", .comment = "All should be powered off NOW"}, // {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER}, }; +/** + * @brief weather_level - set/clear weather level + * @param newlvl - -1 for getter or 0..3 for setter + * @return current weather level + */ +int weather_level(int newlvl){ + if(newlvl > -1 && newlvl <= WEATHER_PROHIBITED){ + pthread_mutex_lock(&datamutex); + uint32_t curt = time(NULL); + int oldlvl = collected_data[NCOMMWEATH].value.u; + collected_data[NCOMMWEATH].value.u = newlvl; + collected_data[NCOMMWEATH].time = curt; + sprintf(collected_data[NAHTUNGRSN].value.str, "MANUAL"); + collected_data[NAHTUNGRSN].time = curt; + collected_data[NLASTAHTUNG].value.u = curt; + collected_data[NLASTAHTUNG].time = curt; + pthread_mutex_unlock(&datamutex); + LOGWARN("Manual changing of weather level from %d to %d", oldlvl, newlvl); + } + pthread_mutex_lock(&datamutex); + int curlevel = collected_data[NCOMMWEATH].value.u; + pthread_mutex_unlock(&datamutex); + return curlevel; +} + +/** + * @brief force_off - set/clear `force off` flag + * @param flag - 1 to set, 0 to clear or -1 to get + * @return current value + */ +int force_off(int flag){ + if(flag > -1 && flag < 2){ + pthread_mutex_lock(&datamutex); + uint32_t curt = time(NULL); + int oldval = collected_data[NFORCEDSHTDN].value.u; + collected_data[NFORCEDSHTDN].value.u = (uint32_t)flag; + if(flag) collected_data[NFORCEDSHTDN].time = curt; + sprintf(collected_data[NAHTUNGRSN].value.str, "MANUAL"); + collected_data[NAHTUNGRSN].time = curt; + collected_data[NLASTAHTUNG].value.u = curt; + collected_data[NLASTAHTUNG].time = curt; + pthread_mutex_unlock(&datamutex); + LOGWARN("Manual changing of FORCED SHUTDOWN from %d to %d", oldval, flag); + } + pthread_mutex_lock(&datamutex); + flag = collected_data[NFORCEDSHTDN].value.u; + pthread_mutex_unlock(&datamutex); + return flag; +} + typedef struct{ double array[MAX_HISTORY]; double sum; @@ -195,10 +245,20 @@ int get_collected(val_t *val, int N){ return TRUE; } -// take only data with `sense value` less than collected have -static void fix_new_data(val_t *collected, val_t *fresh){ +/** + * @brief fix_new_data - take only data with `sense value` less than collected have and more recent + * @param collected - pointer to collected data + * @param fresh - pointer to fresh data + * @param force - ==1 to force changing even if this data is older + */ +static void fix_new_data(val_t *collected, const val_t *fresh, int force){ if(!collected || !fresh) return; - if(collected->time > fresh->time) return; + if(collected->time >= fresh->time){ + if(!force) return; + //DBG("Forced, collected=%g, fresh=%g", val2d(collected), val2d(fresh)); + if(collected->time - fresh->time > 60) return; + //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(collected->sense < fresh->sense) return; @@ -253,9 +313,15 @@ static void fix_new_data(val_t *collected, val_t *fresh){ } } -// increase weather level if need, also check force shutdown flags -// @return 0 if level wasn't changed, or +1 if was increased -static int chkweatherlevel(int *curlevel, double curvalue, weather_cond_t const *curcond){ +/** + * @brief chkweatherlevel - increase weather level if need, also check force shutdown flags + * @param curlevel - current max weather level + * @param curvalue - current value of sensor data + * @param curcond - conditions for given value + * @return 0 if level wasn't changed, or +1 if was increased + */ +static int chkweatherlevel(uint32_t *curlevel, double curvalue, weather_cond_t const *curcond){ + int rtn = 0; double good = curcond->good, bad = curcond->bad, terrible = curcond->terrible, prohibited = curcond->prohibited; int haveproh = (prohibited > terrible) ? 1 : 0; // value have `prohibited` field if(curcond->negflag){ // negate @@ -268,30 +334,31 @@ static int chkweatherlevel(int *curlevel, double curvalue, weather_cond_t const int newlevel = -1; if(haveproh && curvalue > prohibited){ newlevel = WEATHER_PROHIBITED; - DBG("---> new level is PROHIBITED, val=%g", curvalue); + DBG("---> new level is PROHIBITED, val=%g", (curcond->negflag) ? -curvalue : curvalue); }else if(curvalue > terrible){ newlevel = WEATHER_TERRIBLE; - DBG("---> new level is TERRIBLE, val=%g", curvalue); + DBG("---> new level is TERRIBLE, val=%g", (curcond->negflag) ? -curvalue : curvalue); }else if(curvalue > bad) newlevel = WEATHER_BAD; else if(curvalue < good) newlevel = WEATHER_GOOD; if(newlevel == -1) return 0; time_t curt = time(NULL); if(curcond->shtdnflag && newlevel >= WEATHER_TERRIBLE){ - DBG("Forced shutdown flag is set, curvalue: %g", curvalue); + DBG("Forced shutdown flag is set, curvalue: %g", (curcond->negflag) ? -curvalue : curvalue); // set to one collected data flag and its time val_t *f = &collected_data[NFORCEDSHTDN]; - f->value.i = 1; + f->value.u = 1; f->time = (int) curt; // and set current weather level to prohibited - *curlevel = WEATHER_PROHIBITED; + newlevel = WEATHER_PROHIBITED; + rtn = 1; } - if(newlevel > *curlevel){ + if((uint32_t)newlevel > *curlevel){ // TODO: add logging - DBG("local level increased to %d", newlevel); - *curlevel = newlevel; - return 1; + //DBG("local level increased to %d", newlevel); + *curlevel = (uint32_t)newlevel; + rtn = 1; } - return 0; + return rtn; } // conditions for "bad weather" flag (if it ==1 set BAD WEATH) @@ -310,7 +377,7 @@ void refresh_sensval(sensordata_t *s){ val_t value; if(!s || !s->get_value) return; //if(poll_time == 0) poll_time = get_pollT(); - int curlevel = 0; // this is worse weather leavel, start from best + uint32_t curlevel = 0; // this is worse weather leavel, start from best time_t curtime = time(NULL); double dir = -100., dir2 = -100.; // mean wind directions //DBG("%d meteo values", s->Nvalues); @@ -319,23 +386,22 @@ void refresh_sensval(sensordata_t *s){ if(!s->get_value(s, &value, i) || value.sense > VAL_RECOMMENDED) continue; //DBG("got value"); int idx = -1; - double curvalue; - switch(value.type){ - case VALT_UINT: curvalue = (double) value.value.u; break; - case VALT_INT: curvalue = (double) value.value.i; break; - case VALT_FLOAT: curvalue = (double) value.value.f; break; - default: curvalue = 0.; - } + double curvalue = val2d(&value); const weather_cond_t *curcond = NULL; switch(value.meaning){ case IS_WIND: idx = NWIND; curcond = &WeatherConf.wind; + // protect collected wind speeds from destruction in case of simultaneous acces from different plugins + pthread_mutex_lock(&datamutex); add_windspeed(&windspeeds, curvalue, curtime); + pthread_mutex_unlock(&datamutex); break; case IS_WINDDIR: idx = NWINDDIR; + pthread_mutex_lock(&datamutex); wind_dir_add(collected_data[NWIND].value.f, value.value.f, &dir, &dir2); + pthread_mutex_unlock(&datamutex); break; case IS_HUMIDITY: idx = NHUMIDITY; @@ -389,11 +455,18 @@ void refresh_sensval(sensordata_t *s){ if(idx < 0 || idx >= NAMOUNT_OF_DATA) continue; //DBG("IDX=%d", idx); pthread_mutex_lock(&datamutex); - fix_new_data(&collected_data[idx], &value); + int force = 0; if(curcond){ - if(1 == chkweatherlevel(&curlevel, curvalue, 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 + force = 1; + if(collected_data[NFORCEDSHTDN].value.u - oldshtdn == 1){ // got shutdown + LOGWARN("Forced shutdown flag is set by '%s' of '%s'", reason, s->name); + } + } } + fix_new_data(&collected_data[idx], &value, force); pthread_mutex_unlock(&datamutex); } pthread_mutex_lock(&datamutex); @@ -411,26 +484,34 @@ void refresh_sensval(sensordata_t *s){ collected_data[NWINDMAX1].value.f = (float) get_max_forT(&windspeeds, curtime - T_ONE_HOUR); collected_data[NWINDMAX1].time = curtime; //DBG("check ahtung"); - if(Forbidden) collected_data[NCOMMWEATH].value.i = WEATHER_PROHIBITED; + if(Forbidden) collected_data[NCOMMWEATH].value.u = WEATHER_PROHIBITED; else{ - if(collected_data[NCOMMWEATH].value.i > curlevel){ // check timeout to make level lower - // DBG("curtime: %zd, curahtt: %d, diff: %zd, delay: %d", curtime, collected_data[NLASTAHTUNG].value.i, curtime - collected_data[NLASTAHTUNG].value.i, WeatherConf.ahtung_delay); - if(curtime - collected_data[NLASTAHTUNG].value.i > WeatherConf.ahtung_delay){ - DBG("newlevel: %d, current: %d DECREASED", curlevel, collected_data[NCOMMWEATH].value.i); - collected_data[NCOMMWEATH].value.i = curlevel; - collected_data[NLASTAHTUNG].value.i = curtime; - if(1 < snprintf(collected_data[NAHTUNGRSN].value.str, KEY_LEN+1, "%s", reason)) - collected_data[NAHTUNGRSN].time = curtime; + 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); + if(curtime - collected_data[NLASTAHTUNG].value.u > WeatherConf.ahtung_delay){ + DBG("newlevel: %d, current: %d DECREASED", curlevel, collected_data[NCOMMWEATH].value.u); + if(curlevel < WEATHER_TERRIBLE){ // clear forced shutdown flag + if(collected_data[NFORCEDSHTDN].value.u){ + LOGMSGADD("Clear forced shutdown flag"); + DBG("Clear FORCED SHUTDOWN flag"); + collected_data[NCOMMWEATH].value.u = WEATHER_TERRIBLE; + }else collected_data[NCOMMWEATH].value.u = curlevel; + collected_data[NFORCEDSHTDN].value.u = 0; + }else --collected_data[NCOMMWEATH].value.u; + collected_data[NCOMMWEATH].time = curtime; + collected_data[NLASTAHTUNG].value.u = curtime; + LOGMSG("Station '%s', decrease weather level to %d", s->name, collected_data[NCOMMWEATH].value.u); } }else{ - if(collected_data[NCOMMWEATH].value.i < curlevel){ // set to worse - DBG("newlevel: %d, current: %d INCREASED", curlevel, collected_data[NCOMMWEATH].value.i); - collected_data[NCOMMWEATH].value.i = curlevel; + if(collected_data[NCOMMWEATH].value.u < curlevel){ // set to worse + DBG("newlevel: %d, current: %d INCREASED", curlevel, collected_data[NCOMMWEATH].value.u); + LOGWARN("Station '%s', sensor '%s', increase weather level to %d", s->name, reason, curlevel); + collected_data[NCOMMWEATH].value.u = curlevel; if(1 < snprintf(collected_data[NAHTUNGRSN].value.str, KEY_LEN+1, "%s", reason)) collected_data[NAHTUNGRSN].time = curtime; } if(curlevel){ - collected_data[NLASTAHTUNG].value.i = 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[NAHTUNGRSN].time = curtime; } } @@ -441,17 +522,16 @@ void refresh_sensval(sensordata_t *s){ //DBG("Refreshed"); } -// set/clear `forbid` flag +// set/clear `forbid` flag (by signals USR1 and USR2) void forbid_observations(int f){ if(f) Forbidden = 1; else Forbidden = 0; int curt = (int) time(NULL); - pthread_mutex_lock(&datamutex); - collected_data[NLASTAHTUNG].value.i = curt; + // don't use mutexes here as this function called from signal handler + collected_data[NLASTAHTUNG].value.u = curt; collected_data[NLASTAHTUNG].time = curt; sprintf(collected_data[NAHTUNGRSN].value.str, "FORBID"); collected_data[NAHTUNGRSN].time = curt; - pthread_mutex_unlock(&datamutex); DBG("Change FORBID status to %d", f); } diff --git a/Daemons/weatherdaemon_multimeteo/mainweather.h b/Daemons/weatherdaemon_multimeteo/mainweather.h index ac01c10..0e6c93b 100644 --- a/Daemons/weatherdaemon_multimeteo/mainweather.h +++ b/Daemons/weatherdaemon_multimeteo/mainweather.h @@ -59,5 +59,10 @@ int get_collected(val_t *val, int N); void forbid_observations(int f); int is_forbidden(); + void refresh_sensval(sensordata_t *s); + +int force_off(int flag); +int weather_level(int new); + //void run_mainweather(); diff --git a/Daemons/weatherdaemon_multimeteo/plugins/dummy.c b/Daemons/weatherdaemon_multimeteo/plugins/dummy.c index c9c1d35..4ce0cf8 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/dummy.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/dummy.c @@ -55,8 +55,8 @@ static void *mainthread(void *s){ //if(!sensor->values[5].value.u && drand48() > 0.7) sensor->values[5].value.u = 1; time_t cur = time(NULL); for(int i = 0; i < NS-1; ++i) sensor->values[i].time = cur; - f = sensor->values[6].value.f - (drand48() - 0.2) * 100.; - if(f > 0. && f < 60000){ + f = sensor->values[6].value.f - (drand48() - 0.52); + if(f > 0. && f < 60){ sensor->values[6].value.f = f; sensor->values[6].time = cur; } @@ -84,7 +84,7 @@ sensordata_t *sensor_new(int N, time_t pollt, int _U_ fd){ s->values[3].value.f = 600.; s->values[4].value.f = 89.; s->values[5].value.u = 0; - s->values[6].value.f = 54000.; + s->values[6].value.f = 4.5; s->PluginNo = N; if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){ s->kill(s); diff --git a/Daemons/weatherdaemon_multimeteo/sensors.c b/Daemons/weatherdaemon_multimeteo/sensors.c index afc99fc..7ee944c 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.c +++ b/Daemons/weatherdaemon_multimeteo/sensors.c @@ -300,3 +300,14 @@ int change_val_sense(sensordata_t *s, int idx, valsense_t sense){ s->values[idx].sense = sense; return TRUE; } + +double val2d(const val_t *value){ + double curvalue; + switch(value->type){ + case VALT_UINT: curvalue = (double) value->value.u; break; + case VALT_INT: curvalue = (double) value->value.i; break; + case VALT_FLOAT: curvalue = (double) value->value.f; break; + default: curvalue = 0.; + } + return curvalue; +} diff --git a/Daemons/weatherdaemon_multimeteo/sensors.h b/Daemons/weatherdaemon_multimeteo/sensors.h index 71c5e4e..fba8794 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.h +++ b/Daemons/weatherdaemon_multimeteo/sensors.h @@ -33,5 +33,6 @@ int format_sensval(const val_t *v, char *buf, int buflen, int Np); int format_msrmttm(time_t t, char *buf, int buflen, int Np); int change_val_sense(sensordata_t *s, int idx, valsense_t sense); int set_pollT(time_t t); +double val2d(const val_t *v); void get_fieldname(const val_t *v, char buf[KEY_LEN+1]); time_t get_pollT(); diff --git a/Daemons/weatherdaemon_multimeteo/server.c b/Daemons/weatherdaemon_multimeteo/server.c index 1b1c606..619f81b 100644 --- a/Daemons/weatherdaemon_multimeteo/server.c +++ b/Daemons/weatherdaemon_multimeteo/server.c @@ -126,7 +126,7 @@ static sl_sock_hresult_e gethandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item // get parameters' level static sl_sock_hresult_e getlvlhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item, const char *req){ - if(!client) if(!client) return RESULT_FAIL; + if(!client)return RESULT_FAIL; int N = get_nplugins(); if(N < 1) return RESULT_FAIL; val_t v; @@ -160,7 +160,7 @@ static sl_sock_hresult_e getlvlhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *i // set parameters' level; format: setlevel=N1:par=level,...,N1:par=level... // Nx - "station" number, par - parameter name (like "HUMIDITY"), level - new level (0..3) static sl_sock_hresult_e setlvlhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item, const char *req){ - if(!client) if(!client) return RESULT_FAIL; + if(!client) return RESULT_FAIL; int N = get_nplugins(); if(N < 1) return RESULT_FAIL; if(!req) return RESULT_BADVAL; @@ -221,11 +221,15 @@ static sl_sock_hresult_e setlvlhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *i break; } s = end; + val_t oldval; + int olds = -1; + if(sd->get_value && sd->get_value(sd, &oldval, validx)) olds = oldval.sense; DBG("%ld\n", val); if(!change_val_sense(sd, validx, (valsense_t)val)){ result = RESULT_BADVAL; break; } + LOGWARN("Change '%s' of '%s' sense from %d to %ld", sd->name, buf, olds, val); while(isspace((unsigned char)*s)) s++; if(*s == ','){ // omit delimeter ++s; @@ -239,6 +243,44 @@ static sl_sock_hresult_e setlvlhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *i return result; } +static sl_sock_hresult_e forbidhandler(sl_sock_t *client, sl_sock_hitem_t *item, const char *req){ + char buf[256]; + if(!client) return RESULT_FAIL; + if(req){ // setter + int l; + if(!sl_str2i(&l, req)) return RESULT_BADVAL; + forbid_observations(l); + LOGWARN("Manual set by socket command FORBID=%d", is_forbidden()); + } + snprintf(buf, 256, "%s = %d\n", item->key, is_forbidden()); + sl_sock_sendstrmessage(client, buf); + return RESULT_SILENCE; +} + +static sl_sock_hresult_e forceoffhandler(sl_sock_t *client, sl_sock_hitem_t *item, const char *req){ + char buf[256]; + if(!client) return RESULT_FAIL; + int flag = -1; + if(req){ // setter + if(!sl_str2i(&flag, req) || flag < 0 || flag > 1) return RESULT_BADVAL; + } + snprintf(buf, 256, "%s = %d\n", item->key, force_off(flag)); + sl_sock_sendstrmessage(client, buf); + return RESULT_SILENCE; +} + +static sl_sock_hresult_e wlevhandler(sl_sock_t *client, sl_sock_hitem_t *item, const char *req){ + char buf[256]; + if(!client) return RESULT_FAIL; + int newlevel = -1; + if(req){ // setter + if(!sl_str2i(&newlevel, req) || newlevel < 0 || newlevel > WEATHER_PROHIBITED) return RESULT_BADVAL; + } + snprintf(buf, 256, "%s = %d\n", item->key, weather_level(newlevel)); + sl_sock_sendstrmessage(client, buf); + return RESULT_SILENCE; +} + // graceful closing socket: let client know that he's told to fuck off static void toomuch(int fd){ const char *m = "Try later: too much clients connected\n"; @@ -288,27 +330,14 @@ static sl_sock_hitem_t nethandlers[] = { // net - only getters and client-only s {NULL, NULL, NULL, NULL} }; static sl_sock_hitem_t localhandlers[] = { // local - full amount of setters/getters + {forbidhandler, "forbid", "get/set/clear MANUAL FORBID flag", NULL}, + {forceoffhandler, "forceoff", "get/set/clear FORCE SHUTDOWN flag", NULL}, {setlvlhandler, "setlevel", "set 'sense level' (0..3) for given plugin parameters, e.g. setlevel=1:WIND=3,HUMIDITY=3 - disable fields for station 1", NULL}, + {wlevhandler, "weathlevel", "set/get current weather level (0..3): goog/bad/terrible/prohibited", NULL}, COMMONHANDLERS {NULL, NULL, NULL, NULL} }; -#if 0 -// common parsers for both net and local sockets -static void *cmdparser(void *U){ - if(!U) return NULL; - sl_sock_t *s = (sl_sock_t*) U; - while(s && s->connected){ - if(!s->rthread){ - LOGERR("Server's handlers' thread is dead"); - break; - } - } - LOGDBG("cmdparser(): exit"); - return NULL; -} -#endif - int start_servers(const char *netnode, const char *sockpath){ if(!netnode || !sockpath){ LOGERR("start_servers(): need arguments"); @@ -334,35 +363,11 @@ int start_servers(const char *netnode, const char *sockpath){ sl_sock_dischandler(localsocket, disconnected); sl_sock_defmsghandler(netsocket, defhandler); sl_sock_defmsghandler(localsocket, defhandler); -#if 0 - if(pthread_create(&netthread, NULL, cmdparser, (void*)netsocket)){ - LOGERR("Can't run server's net thread"); - goto errs; - } - if(pthread_create(&locthread, NULL, cmdparser, (void*)localsocket)){ - LOGERR("Can't run server's local thread"); - goto errs; - } -#endif return TRUE; -#if 0 -errs: - sl_sock_delete(&localsocket); - sl_sock_delete(&netsocket); - return FALSE; -#endif } void kill_servers(){ - //pthread_cancel(locthread); - //pthread_cancel(netthread); - //LOGMSG("Server threads canceled"); - //usleep(500); sl_sock_delete(&localsocket); sl_sock_delete(&netsocket); LOGMSG("Server sockets destroyed"); - //usleep(500); - //pthread_join(locthread, NULL); - //pthread_join(netthread, NULL); - //LOGMSG("Server threads are dead"); }