diff --git a/Daemons/weatherdaemon_multimeteo/mainweather.c b/Daemons/weatherdaemon_multimeteo/mainweather.c index 1128b7f..8b45ee4 100644 --- a/Daemons/weatherdaemon_multimeteo/mainweather.c +++ b/Daemons/weatherdaemon_multimeteo/mainweather.c @@ -55,21 +55,24 @@ enum{ NAMOUNT_OF_DATA }; +// starting sense values are VAL_BROKEN except of calculated values +// they would be changed later in `fix_new_data` to lowest level static val_t collected_data[NAMOUNT_OF_DATA] = { - [NWIND] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_WIND}, - [NWINDMAX] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDMAX", .comment = "Maximal wind speed for last 24 hours"}, - [NWINDMAX1] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDMAX1", .comment = "Maximal wind speed for last hour"}, - [NWINDDIR] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_WINDDIR}, - [NWINDDIR1] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDDIR1", .comment = "Mean wind speed direction for last hour"}, - [NWINDDIR2] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDDIR2", .comment = "Mean wind speed^2 direction for last hour"}, - [NHUMIDITY] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_HUMIDITY}, - [NAMB_TEMP] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP}, - [NPRESSURE] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_PRESSURE}, - [NPRECIP] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_PRECIP}, - [NPRECIP_LEVEL] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, - [NMIST] = {.sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_MIST}, - [NCLOUDS] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_CLOUDS}, - [NSKYTEMP] = {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_SKYTEMP}, + [NWIND] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_WIND}, + [NWINDMAX] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDMAX", .comment = "Maximal wind speed for last 24 hours"}, + [NWINDMAX1] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDMAX1", .comment = "Maximal wind speed for last hour"}, + [NWINDDIR] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_WINDDIR}, + [NWINDDIR1] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDDIR1", .comment = "Mean wind speed direction for last hour"}, + [NWINDDIR2] = {.sense = VAL_RECOMMENDED, .type = VALT_FLOAT, .meaning = IS_OTHER, .name = "WINDDIR2", .comment = "Mean wind speed^2 direction for last hour"}, + [NHUMIDITY] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_HUMIDITY}, + [NAMB_TEMP] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_AMB_TEMP}, + [NPRESSURE] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_PRESSURE}, + [NPRECIP] = {.sense = VAL_BROKEN, .type = VALT_UINT, .meaning = IS_PRECIP}, + [NPRECIP_LEVEL] = {.sense = VAL_BROKEN, .type = VALT_FLOAT, .meaning = IS_PRECIP_LEVEL}, + [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}, + // these are calculated values [NCOMMWEATH] = {.value.i = 0, .sense = VAL_OBLIGATORY, .type = VALT_UINT, .meaning = IS_OTHER, .name = "WEATHER", .comment = "Weather level (0 - good, 3 - obs. prohibited)"}, [NLASTAHTUNG] = {.value.i = 0, .sense = VAL_RECOMMENDED, .type = VALT_UINT, .meaning = IS_OTHER, .name = "EVTTIME", .comment = "UNIX-time of last weather level increasing"}, // {.sense = VAL_OBLIGATORY, .type = VALT_FLOAT, .meaning = IS_OTHER}, @@ -181,11 +184,18 @@ 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){ if(!collected || !fresh) return; + if(collected->time > fresh->time) return; + // lower `collected` level if data is too old + if(fresh->time - collected->time > 60) collected->sense = VAL_UNNECESSARY; + if(collected->sense < fresh->sense) return; + if(collected->sense != fresh->sense) collected->sense = fresh->sense; // take new lower level + //DBG("Refresh collected value"); collected->time = fresh->time; if(collected->type == fresh->type){ // good case - DBG("Types are the same"); + //DBG("Types are the same"); collected->value = fresh->value; return; } @@ -195,11 +205,11 @@ static void fix_new_data(val_t *collected, val_t *fresh){ switch(fresh->type){ case VALT_INT: collected->value.u = (uint32_t) fresh->value.i; - DBG("i->u"); + //DBG("i->u"); break; case VALT_FLOAT: collected->value.u = (uint32_t) fresh->value.f; - DBG("f->u"); + //DBG("f->u"); default: break; } break; @@ -207,11 +217,11 @@ static void fix_new_data(val_t *collected, val_t *fresh){ switch(fresh->type){ case VALT_UINT: collected->value.i = (int32_t) fresh->value.u; - DBG("u->i"); + //DBG("u->i"); break; case VALT_FLOAT: collected->value.i = (int32_t) fresh->value.f; - DBG("f->i"); + //DBG("f->i"); default: break; } break; @@ -219,11 +229,11 @@ static void fix_new_data(val_t *collected, val_t *fresh){ switch(fresh->type){ case VALT_UINT: collected->value.f = (float) fresh->value.u; - DBG("u->f"); + //DBG("u->f"); break; case VALT_INT: collected->value.f = (float) fresh->value.i; - DBG("i->f"); + //DBG("i->f"); default: break; } break; @@ -257,7 +267,7 @@ static void chkweatherlevel(int *curlevel, double curvalue, weather_cond_t *curc } void refresh_sensval(sensordata_t *s){ - FNAME(); + //FNAME(); static time_t poll_time = 0; val_t value; if(!s || !s->get_value) return; @@ -266,11 +276,11 @@ void refresh_sensval(sensordata_t *s){ int curahtungtime = collected_data[NLASTAHTUNG].value.i; time_t curtime = time(NULL); 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){ - DBG("\nTry to get %dth value", i); - if(!s->get_value(s, &value, i)) continue; - DBG("got value"); + //DBG("\nTry to get %dth value", i); + if(!s->get_value(s, &value, i) || value.sense > VAL_RECOMMENDED) continue; + //DBG("got value"); int idx = -1; double curvalue; weather_cond_t *curcond = NULL; @@ -326,13 +336,7 @@ void refresh_sensval(sensordata_t *s){ default : break; } if(idx < 0 || idx >= NAMOUNT_OF_DATA) continue; - DBG("IDX=%d", idx); - time_t freshdelay = (s->PluginNo == 0) ? 0 : 90; // use data of less imrortant plugins only if our data is too old - time_t curmt = collected_data[idx].time + freshdelay; - if(value.time < curmt){ - DBG("Data too old (value: %zd, curr: %zd", value.time, curmt); - continue; // old data - } + //DBG("IDX=%d", idx); pthread_mutex_lock(&datamutex); fix_new_data(&collected_data[idx], &value); pthread_mutex_unlock(&datamutex); @@ -352,14 +356,14 @@ void refresh_sensval(sensordata_t *s){ collected_data[NWINDMAX].time = curtime; collected_data[NWINDMAX1].value.f = (float) get_max_forT(&windspeeds, curtime - T_ONE_HOUR); collected_data[NWINDMAX1].time = curtime; - DBG("check ahtung"); + //DBG("check ahtung"); if(Forbidden) collected_data[NCOMMWEATH].value.i = WEATHER_PROHIBITED; else collected_data[NCOMMWEATH].value.i = curlevel; if(collected_data[NLASTAHTUNG].value.i < curahtungtime) collected_data[NLASTAHTUNG].value.i = curahtungtime; collected_data[NCOMMWEATH].time = curtime; collected_data[NLASTAHTUNG].time = curtime; pthread_mutex_unlock(&datamutex); - DBG("Refreshed"); + //DBG("Refreshed"); } void forbid_observations(int f){ diff --git a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c index b3813a9..0e5d5bf 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c @@ -43,7 +43,7 @@ static void *mainthread(void *s){ sensordata_t *sensor = (sensordata_t *)s; while(1){ if(check_shm_block(&sdat)){ - DBG("Got next"); + //DBG("Got next"); time_t tnow = time(NULL); pthread_mutex_lock(&sensor->valmutex); for(int i = 0; i < NAMOUNT; ++i) @@ -52,7 +52,7 @@ static void *mainthread(void *s){ sensor->values[NPRESSURE].value.f = val_B; sensor->values[NAMB_TEMP].value.f = val_T1; sensor->values[NHUMIDITY].value.f = val_Hmd; - DBG("Tprecip=%.1f, tnow=%.1f", Precip_time, sl_dtime()); + //DBG("Tprecip=%.1f, tnow=%.1f", Precip_time, sl_dtime()); sensor->values[NPRECIP].value.u = (tnow - (time_t)Precip_time < 60) ? 1 : 0; pthread_mutex_unlock(&sensor->valmutex); if(sensor->freshdatahandler) sensor->freshdatahandler(sensor); diff --git a/Daemons/weatherdaemon_multimeteo/sensors.c b/Daemons/weatherdaemon_multimeteo/sensors.c index 9ede2d3..b056545 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.c +++ b/Daemons/weatherdaemon_multimeteo/sensors.c @@ -85,9 +85,10 @@ void *open_plugin(const char *name){ * @param station - pointer to N'th station opened */ static void dumpsensors(struct sensordata_t* station){ - FNAME(); + //FNAME(); if(!station || !station->get_value || station->Nvalues < 1) return; refresh_sensval(station); +#if 0 DBG("New values..."); #ifdef EBUG char buf[FULL_LEN+1]; @@ -110,6 +111,7 @@ static void dumpsensors(struct sensordata_t* station){ } } #endif +#endif } /** @@ -164,6 +166,32 @@ void closeplugins(){ nplugins = 0; } +static const char* const NM[IS_OTHER] = { // names of standard fields + [IS_WIND] = "WIND", + [IS_WINDDIR] = "WINDDIR", + [IS_HUMIDITY] = "HUMIDITY", + [IS_AMB_TEMP] = "EXTTEMP", + [IS_INNER_TEMP] = "INTTEMP", + [IS_HW_TEMP] = "HWTEMP", // mirror? + [IS_PRESSURE] = "PRESSURE", + [IS_PRECIP] = "PRECIP", + [IS_PRECIP_LEVEL]="PRECIPLV", + [IS_MIST] = "MIST", + [IS_CLOUDS] = "CLOUDS", + [IS_SKYTEMP] = "SKYTEMP" +}; + +// format "sense" of sensor, like "[WIND][1]=2" +int format_senssense(const val_t *v, char *buf, int buflen, int Np){ + if(!v || !buf || buflen < 1) return -1; + int idx = v->meaning; + const char *name = (idx < IS_OTHER) ? NM[idx] : v->name; + int got; + if(Np > -1) got = snprintf(buf, buflen, "[%s][%d]=%d", name, Np, v->sense); + else got = snprintf(buf, buflen, "[%s]=%d", name, v->sense); + return (got < buflen) ? got : buflen; // full or truncated +} + /** * @brief format_sensval - snprintf sensor's value into buffer * @param v - value to get @@ -173,8 +201,7 @@ void closeplugins(){ * @return amount of symbols printed or -1 if error */ int format_sensval(const val_t *v, char *buf, int buflen, int Np){ - --buflen; // for trailing zero - if(!v || !buf || buflen < FULL_LEN) return -1; + if(!v || !buf || buflen < 1) return -1; char strval[VAL_LEN+1]; switch(v->type){ case VALT_UINT: snprintf(strval, VAL_LEN, "%u", v->value.u); break; @@ -182,20 +209,6 @@ int format_sensval(const val_t *v, char *buf, int buflen, int Np){ case VALT_FLOAT: snprintf(strval, VAL_LEN, "%.2f", v->value.f); break; default: sprintf(strval, "'ERROR'"); } - const char* const NM[IS_OTHER] = { // names of standard fields - [IS_WIND] = "WIND", - [IS_WINDDIR] = "WINDDIR", - [IS_HUMIDITY] = "HUMIDITY", - [IS_AMB_TEMP] = "EXTTEMP", - [IS_INNER_TEMP] = "INTTEMP", - [IS_HW_TEMP] = "HWTEMP", // mirror? - [IS_PRESSURE] = "PRESSURE", - [IS_PRECIP] = "PRECIP", - [IS_PRECIP_LEVEL]="PRECIPLV", - [IS_MIST] = "MIST", - [IS_CLOUDS] = "CLOUDS", - [IS_SKYTEMP] = "SKYTEMP" - }; const char* const CMT[IS_OTHER] = { // comments for standard fields [IS_WIND] = "Wind, m/s", [IS_WINDDIR] = "Instant wind direction, degr (CW from north to FROM)", @@ -222,7 +235,7 @@ int format_sensval(const val_t *v, char *buf, int buflen, int Np){ int got; if(Np > -1) got = snprintf(buf, buflen, "%s[%d]=%s / %s", name, Np, strval, comment); else got = snprintf(buf, buflen, "%s=%s / %s", name, strval, comment); - return got; + return (got < buflen) ? got : buflen; // full or truncated } // the same for measurement time formatting @@ -234,3 +247,35 @@ int format_msrmttm(time_t t, char *buf, int buflen){ strftime(cmt, COMMENT_LEN, "%F %T", T); return snprintf(buf, buflen, "TMEAS=%zd / Last measurement time: %s", t, cmt); } + +// find sensor's value by its name; @return index or -1 if not found +int find_val_by_name(sensordata_t *s, const char *name){ + if(!s || !name) return -1; + if(s->Nvalues < 1) return -1; + // check standard "meaning" + valmeaning_t mnng = 0; + for(; mnng < IS_OTHER; ++mnng){ + if(0 == strcmp(NM[mnng], name)) break; // found in standard + } + for(int i = 0; i < s->Nvalues; ++i){ + val_t val; + if(!s->get_value(s, &val, i) || val.meaning != mnng) continue; + if(mnng != IS_OTHER){ // found in standard values + return i; + }else{ // non-standard: check by name + if(0 == strcmp(val.name, name)){ // found by name + return i; + } + } + } + return -1; // not found +} + +// chane 'sense' field of given meteostation for value with index=`idx`; @return FALSE if failed +int change_val_sense(sensordata_t *s, int idx, valsense_t sense){ + if(!s || sense < 0 || sense >= VAL_AMOUNT) return FALSE; + int N = s->Nvalues; + if(idx < 0 || idx >= N) return FALSE; + s->values[idx].sense = sense; + return TRUE; +} diff --git a/Daemons/weatherdaemon_multimeteo/sensors.h b/Daemons/weatherdaemon_multimeteo/sensors.h index 14ccb79..802faa3 100644 --- a/Daemons/weatherdaemon_multimeteo/sensors.h +++ b/Daemons/weatherdaemon_multimeteo/sensors.h @@ -27,7 +27,10 @@ int openplugins(char **paths, int N); void closeplugins(); sensordata_t *get_plugin(int N); int get_nplugins(); +int find_val_by_name(sensordata_t *s, const char *name); +int format_senssense(const val_t *v, char *buf, int buflen, int Np); int format_sensval(const val_t *v, char *buf, int buflen, int Np); int format_msrmttm(time_t t, char *buf, int buflen); +int change_val_sense(sensordata_t *s, int idx, valsense_t sense); int set_pollT(time_t t); time_t get_pollT(); diff --git a/Daemons/weatherdaemon_multimeteo/server.c b/Daemons/weatherdaemon_multimeteo/server.c index 8e05edd..582bcd5 100644 --- a/Daemons/weatherdaemon_multimeteo/server.c +++ b/Daemons/weatherdaemon_multimeteo/server.c @@ -16,7 +16,9 @@ * along with this program. If not, see . */ +#include #include +#include #include #include @@ -55,26 +57,34 @@ static sl_sock_hresult_e listhandler(sl_sock_t *client, _U_ sl_sock_hitem_t *ite return RESULT_SILENCE; } +// get N'th plugin or send error message +sensordata_t *get_plugin_w_message(sl_sock_t *client, int N){ + char buf[FULL_LEN]; + sensordata_t *s = NULL; + if(!(s = get_plugin(N)) || (s->Nvalues < 1)){ + snprintf(buf, FULL_LEN, "Can't get plugin[%d]\n", N); + sl_sock_sendstrmessage(client, buf); + return NULL; + } + return s; +} + /** * @brief showdataN - send to user meteodata of Nth station * @param client - client data * @param N - index of station */ static void showdataN(sl_sock_t *client, int N){ - char buf[FULL_LEN+1]; + char buf[FULL_LEN]; val_t v; - sensordata_t *s = NULL; - if(!(s = get_plugin(N)) || (s->Nvalues < 1)){ - snprintf(buf, FULL_LEN, "Can't get plugin[%d]\n", N); - sl_sock_sendstrmessage(client, buf); - return; - } + sensordata_t *s = get_plugin_w_message(client, N); + if(!s) return; time_t oldest = time(NULL) - oldest_interval; uint64_t Tsum = 0; int nsum = 0; for(int i = 0; i < s->Nvalues; ++i){ if(!s->get_value(s, &v, i)) continue; if(v.time < oldest) continue; - if(1 > format_sensval(&v, buf, FULL_LEN+1, N)) continue; + if(1 > format_sensval(&v, buf, FULL_LEN, N)) continue; DBG("formatted: '%s'", buf); sl_sock_sendstrmessage(client, buf); sl_sock_sendbyte(client, '\n'); @@ -82,7 +92,7 @@ static void showdataN(sl_sock_t *client, int N){ } if(nsum > 0){ oldest = (time_t)(Tsum / nsum); - if(0 < format_msrmttm(oldest, buf, FULL_LEN+1)){ // send mean measuring time + if(0 < format_msrmttm(oldest, buf, FULL_LEN)){ // send mean measuring time DBG("Formatted time: '%s'", buf); sl_sock_sendstrmessage(client, buf); sl_sock_sendbyte(client, '\n'); @@ -95,7 +105,7 @@ static void showdataN(sl_sock_t *client, int N){ * @param client - client data */ static void showdata(sl_sock_t *client){ - char buf[FULL_LEN+1]; + char buf[FULL_LEN]; val_t v; int Ncoll = collected_amount(); time_t oldest = time(NULL) - oldest_interval; @@ -103,7 +113,7 @@ static void showdata(sl_sock_t *client){ for(int i = 0; i < Ncoll; ++i){ if(!get_collected(&v, i)){ DBG("Can't get %dth value", i); continue; } if(v.time < oldest){ DBG("%dth value is too old", i); continue; } - if(1 > format_sensval(&v, buf, FULL_LEN+1, -1)){ DBG("Can't format"); continue; } + if(1 > format_sensval(&v, buf, FULL_LEN, -1)){ DBG("Can't format"); continue; } DBG("formatted: '%s'", buf); sl_sock_sendstrmessage(client, buf); sl_sock_sendbyte(client, '\n'); @@ -111,7 +121,7 @@ static void showdata(sl_sock_t *client){ } if(nsum > 0){ oldest = (time_t)(Tsum / nsum); - if(0 < format_msrmttm(oldest, buf, FULL_LEN+1)){ // send mean measuring time + if(0 < format_msrmttm(oldest, buf, FULL_LEN)){ // send mean measuring time DBG("Formatted time: '%s'", buf); sl_sock_sendstrmessage(client, buf); sl_sock_sendbyte(client, '\n'); @@ -134,6 +144,121 @@ static sl_sock_hresult_e gethandler(sl_sock_t *client, _U_ sl_sock_hitem_t *item return RESULT_SILENCE; } +// 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; + int N = get_nplugins(); + if(N < 1) return RESULT_FAIL; + val_t v; + char buf[FULL_LEN]; + if(!req){ // level of collected parameters + DBG("User asks for collected"); + int Ncoll = collected_amount(); + if(Ncoll < 1) return RESULT_FAIL; + for(int i = 0; i < Ncoll; ++i){ + if(!get_collected(&v, i)){ DBG("Can't get %dth value", i); continue; } + if(1 > format_senssense(&v, buf, FULL_LEN, -1)){ DBG("Can't format"); continue; } + sl_sock_sendstrmessage(client, buf); + sl_sock_sendbyte(client, '\n'); + } + }else{ + int n; + if(!sl_str2i(&n, req) || n < 0 || n >= N) return RESULT_BADVAL; + DBG("User asks for %d", n); + sensordata_t *s = get_plugin_w_message(client, n); + if(!s) return RESULT_SILENCE; + for(int i = 0; i < s->Nvalues; ++i){ + if(!s->get_value(s, &v, i)) continue; + if(1 > format_senssense(&v, buf, FULL_LEN, n)){ DBG("Can't format"); continue; } + sl_sock_sendstrmessage(client, buf); + sl_sock_sendbyte(client, '\n'); + } + } + return RESULT_SILENCE; +} + +// 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; + int N = get_nplugins(); + if(N < 1) return RESULT_FAIL; + if(!req) return RESULT_BADVAL; + sl_sock_hresult_e result = RESULT_OK; + char *s = (char *)req; + while(*s){ + while (isspace(*s) || *s == ',') s++; + if (!*s) break; + // get station number + char *end; + long st_num = strtol(s, &end, 10); + if(s == end) break; + s = end; + // wait for ':' + while (isspace(*s)) s++; + if(*s != ':') break; + ++s; + DBG("ST %ld:\n", st_num); + sensordata_t *sd; + if(st_num < 0 || st_num >= N || !(sd = get_plugin((int)st_num))){ + result = RESULT_BADVAL; + break; + } + while(1){ + while(isspace(*s)) ++s; + if(*s == '\0') break; + if(isdigit((unsigned char)*s)) break; // - next block + const char *par_start = s; + while(isalnum(*s)) ++s; + if(par_start == s) break; + int l = (int)(s - par_start); + DBG(" par: %.*s = ", l, par_start); + if(l > KEY_LEN){ + result = RESULT_BADVAL; + break; + } + char buf[KEY_LEN + 1]; + memcpy(buf, par_start, l); + buf[l] = 0; + int validx = find_val_by_name(sd, buf); + // search for given value + if(validx < 0){ + result = RESULT_BADVAL; + break; + } + while(isspace(*s)) ++s; + // fait for '=' + if(*s != '='){ + result = RESULT_BADVAL; + break; + } + ++s; + // get new level + while(isspace(*s)) s++; + long val = strtol(s, &end, 10); + if(s == end){ + result = RESULT_BADVAL; + break; + } + s = end; + DBG("%ld\n", val); + if(!change_val_sense(sd, validx, (valsense_t)val)){ + result = RESULT_BADVAL; + break; + } + while(isspace((unsigned char)*s)) s++; + if(*s == ','){ // omit delimeter + ++s; + continue; + }else{ + if(*s == ';') ++s; // omit ; as block's end + break; + } + } + } + return result; +} + // 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"; @@ -173,6 +298,7 @@ static sl_sock_hresult_e defhandler(struct sl_sock *s, const char *str){ #define COMMONHANDLERS \ {gethandler, "get", "get all meteo or only for given plugin number", NULL}, \ + {getlvlhandler,"chklevel", "check 'sense level' of given plugin parameters", NULL}, \ {listhandler, "list", "show all opened plugins", NULL}, \ {timehandler, "time", "get server's UNIX time", NULL}, @@ -182,6 +308,7 @@ 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 + {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}, COMMONHANDLERS {NULL, NULL, NULL, NULL} }; diff --git a/Daemons/weatherdaemon_multimeteo/weathlib.h b/Daemons/weatherdaemon_multimeteo/weathlib.h index e518c18..ddf2c4d 100644 --- a/Daemons/weatherdaemon_multimeteo/weathlib.h +++ b/Daemons/weatherdaemon_multimeteo/weathlib.h @@ -39,7 +39,8 @@ typedef enum{ VAL_OBLIGATORY, // can't be omitted VAL_RECOMMENDED, // recommended to show VAL_UNNECESSARY, // may be shown by user request - VAL_BROKEN // sensor is broken, omit it + VAL_BROKEN, // sensor is broken, omit it + VAL_AMOUNT // amount of values } valsense_t; // meaning of values