Я хочу использовать Raspberry Pi для записи температуры с помощью серии датчиков. Для этого я пишу программу на C ++, которая использует librrd.
Для каждого подключенного датчика я хочу создать rrd с 12 rra. Следующий вызов должен создать мой требуемый rrd:
rrd_create(mNumberOfCreateParams, mCreateParams);
mNumberOfCreateParams равно 17, а содержимое mCreateParams следующее:
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
Вторая строка меняется каждый раз в соответствии с идентификатором датчика.
Теперь проблема: некоторое время вызов rrd_create работает как задумано, но в какой-то момент он перестает работать и просто создает ошибки при дальнейших вызовах. Это даже верно, если я хочу воссоздать rrd, который был успешно создан ранее.
Изменяя mNumberOfCreateParams, я могу изменить количество проанализированных аргументов. Если параметр находится в диапазоне от 13 до 17, ошибка, возвращаемая rrd_get_error (), это «невозможно разобрать аргумент» («добавлен пробел между» для удобства чтения). Если я позволю функции разобрать от 10 до 12 параметров, она будет «работать» в первый раз и вернет «открытие« @ »: нет такого файла или каталога» во второй раз, потому что в первый раз был создан следующий файл:
изображение созданного файла в файловом браузере
Если количество проанализированных параметров меньше 10, оно работает как задумано.
Нет никакой разницы, если я изменю порядок строк RRA.
Если я вызываю rrdtool create [… такие же параметры, как указано выше] из терминала, все работает нормально, независимо от того, сколько параметров анализируется.
В надежде, что rrd_create снова заработает, я перезапустил несколько раз Raspberry, и он даже работал один раз за короткое время (один запуск моего приложения).
Есть какие-нибудь предложения, что я делаю неправильно или как я могу перевести rrd_create в более стабильное состояние?
Редактировать:
Я использую версию 1.4.7 RRDtool (версия rrdtool в оболочке).
Вот код, который я использую для создания rrd файлов:
// 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);
Так как я сбросил mCreateParams непосредственно перед вызовом rrd_create (…), я думаю, что они не должны быть повреждены
Мой текущий обходной путь использует popen () и mCreateParams используются для создания команды оболочки, вызывающей 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);
Я благодарен за каждый совет.
Когда вы звоните rrd_create(int argc, char**argv)
необходимо передать параметры в ARGV
список, очень похожий на обычный C main()
Функция принимает свои параметры.
В частности, вам не нужно сдавать create
имя функции (это неявно) и, конечно же, argc
Параметр должен соответствовать количеству элементов в argv
массив.
Итак, вкратце: ваш список параметров для rrd_create не должен включать rrdcreate
параметр, и ваш argc
ДОЛЖЕН совпадать с количеством argv
параметры переданы.
Если вы все еще получаете ошибки, возвращенные из rrd_create
вызовите функцию, затем распечатайте сообщение об ошибке.