I want to use my Raspberry Pi to record temperature from a series of sensors. For this purpose I am writing a C++ program which uses librrd.
For every connected sensor I want to create a rrd with 12 rra. The following call should create my wanted rrd:
rrd_create(mNumberOfCreateParams, mCreateParams);
mNumberOfCreateParams is 17 and the content of mCreateParams is the following:
rrdcreate
28-000005fd934f.rrd
--step=300
--no-overwrite
DS:temperature:GAUGE:600:-55:125
RRA:AVERAGE:0.5:1:288
RRA:AVERAGE:0.5:3:672
RRA:AVERAGE:0.5:12:744
RRA:AVERAGE:0.5:72:1464
RRA:MAX:0.5:1:288
RRA:MAX:0.5:3:672
RRA:MAX:0.5:12:744
RRA:MAX:0.5:72:1464
RRA:MIN:0.5:1:288
RRA:MIN:0.5:3:672
RRA:MIN:0.5:12:744
RRA:MIN:0.5:72:1464
The second line changes each time corresponding to the id of the sensor.
Now the problem: Some time the call to rrd_create works as intended but at some point it stops working and just creates errors on further calls. This is even true if I want to recreate an rrd which was successfully created previously.
By changing mNumberOfCreateParams I can alter the number of parsed arguments. If the parameter is in range of 13 to 17 the error returned by rrd_get_error() is "can't parse argument ' ' " (added space between ' for readability). If I let the function parse 10 to 12 parameters it will "work" the first time and return "opening '@': No such file or directory" the second time because the first time the following file was created:
image of created file in file browser
If the number of parsed parameters is below 10 it is working as intended.
There isn't any difference if I change the order of the RRA lines.
If I call rrdtool create [...same parameters as above] from terminal everything works fine indifferent how many parameters are parsed.
In hopes of rrd_create again working I restarted the Raspberry serveral times and it even worked once for a short amount of time (one run of my application).
Are there any suggestions what I am doing wrong or how I can move rrd_create into a more stable state?
Edit: I'm using version 1.4.7 of RRDtool (rrdtool version in shell). Here is the code I'm using for creation of rrd files:
// mCreateParams & mNumberOfCreateParams will be set here
setupRrdCreateParamsDS18B20(lStepSize);
char lCurrentPath[255];
getcwd(lCurrentPath, sizeof(lCurrentPath));
// since I wasn't able to create rrd files outside current working directory I
// change working directory to where I want all files
chdir(DS18B20_PATH.c_str());
// the dump of mCreateParams postet above was created here
int lStatus = rrd_create(mNumberOfCreateParams, mCreateParams);
Since I dumped mCreateParams just before calling rrd_create(...) I think they shouldn't be corrupted.
My current workaround uses popen() and mCreateParams are used to create an shell command calling rrdtool.
stringstream ss;
// create shell command from create params
ss << "rrdtool create ";
for (int i = 1; i < mNumberOfCreateParams - 1; i++) {
ss << mCreateParams[i] << " ";
}
ss << mCreateParams[mNumberOfCreateParams - 1];
// needed for capturing output from executed command
FILE * in;
char buff[512];
if(!(in = popen(ss.str().c_str(), "r"))){
return false;
}
ss.str("");
ss.clear();
// get output
while(fgets(buff, sizeof(buff), in)!=NULL){
ss << buff;
}
lRrdError = ss.str();
ss.str("");
ss.clear();
int lTemp = pclose(in);
// get exit code from rrdtool create
lStatus = WEXITSTATUS(lTemp);
I am thankful for every advise.