Reputation: 35
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.
Upvotes: 0
Views: 1732
Reputation: 4027
When you call rrd_create(int argc, char**argv)
, you need to pass the parameters in an ARGV
list, very similar to the way a normal C main()
function take its parameters.
In particular, you do not need to pass the create
function name (this is implicit) and, of course, the argc
parameter must match the number of elements in the argv
array.
So, in short: your parameter list to rrd_create should not include the rrdcreate
parameter, and your argc
MUST match the number of argv
parameters passed.
If you still get errors returned from the rrd_create
function call, then print out the error message.
Upvotes: 2