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