bool seek_time(const stdString &index_name, const stdString &channel_name, const stdString &start_txt) { epicsTime start; if (!string2epicsTime(start_txt, start)) { fprintf(stderr, "Cannot convert '%s' to time stamp\n", start_txt.c_str()); return false; } IndexFile index(3); index.open(index_name, true); stdString directory; AutoPtr<RTree> tree(index.getTree(channel_name, directory)); if (tree) { RTree::Datablock block; RTree::Node node(tree->getM(), true); int idx; if (tree->searchDatablock(start, node, idx, block)) { stdString s, e; printf("Found block %s - %s\n", epicsTimeTxt(node.record[idx].start, s), epicsTimeTxt(node.record[idx].end, e)); } else printf("Nothing found\n"); } else fprintf(stderr, "Cannot find channel '%s'\n", channel_name.c_str()); return true; }
TEST_CASE DualRawDataReaderTest() { TEST(dual_read_test("../DemoData/index", "fred") == 2*87); epicsTime start; TEST(string2epicsTime("03/23/2004 10:50:42.400561000", start)); TEST(dual_read_test("../DemoData/index", "fred", &start) == 2*10); epicsTime end(start); end += 5; TEST(dual_read_test("../DemoData/index", "fred", &start, &end) == 2*3); TEST(DataFile::clear_cache() == 0); TEST_OK; }
TEST_CASE PlotReaderTest() { TEST(read_test("../DemoData/index", "fred", 10.0) > 0); epicsTime start; TEST(string2epicsTime("03/23/2004 10:50:00", start)); TEST(read_test("../DemoData/index", "fred", 10.0, &start) > 0); epicsTime end(start); end += 15; TEST(read_test("../DemoData/index", "fred", 5.0, &start, &end) > 0); TEST(DataFile::clear_cache() == 0); TEST_OK; }
TEST_CASE RawDataReaderTest() { TEST(read_test("../DemoData/index", "fred") == 87); epicsTime start; TEST(string2epicsTime("03/23/2004 10:50:42.400561000", start)); TEST(read_test("../DemoData/index", "fred", &start) == 10); #ifdef CHECK_AUTO_INDEX TEST(auto_read_test("../DemoData/index", "fred", &start) == 10); TEST(auto_read_test("list_index.xml", "fred", &start) == 10); #endif epicsTime end(start); end += 5; TEST(read_test("../DemoData/index", "fred", &start, &end) == 3); #ifdef CHECK_AUTO_INDEX TEST(auto_read_test("../DemoData/index", "fred", &start, &end) == 3); TEST(auto_read_test("list_index.xml", "fred", &start, &end) == 3); #endif TEST(DataFile::clear_cache() == 0); TEST_OK; }
bool ArchiveParser::handleValue(ChannelIterator &channel) { if (!_value) { printf("Line %zd: no header, yet\n", getLineNo()); return false; } // Format of line: time\tvalue\tstatus const stdString &line = getLine(); size_t valtab = line.find('\t'); if (valtab == stdString::npos) { printf("Line %zd: expected time stamp of value\n%s\n", getLineNo(), line.c_str()); return false; } // Time: stdString text = line.substr(0, valtab); epicsTime time; if (! string2epicsTime(text, time)) { printf("Line %zd: invalid time '%s'\n", getLineNo(), text.c_str()); return false; } _value->setTime(time); stdString status; stdString value = line.substr(valtab+1); size_t stattab = value.find('\t'); if (stattab != stdString::npos) { status = value.substr(stattab+1); value = value.substr(0, stattab); } // Value: if (! _value->parseValue(value)) { printf("Line %zd: invalid value '%s'\n%s\n", getLineNo(), value.c_str(), line.c_str()); return false; } // Status: if (status.empty()) _value->setStatus(0, 0); else { if (!_value->parseStatus(status)) { printf("Line %zd: invalid status '%s'\n%s\n", getLineNo(), status.c_str(), line.c_str()); return false; } } if (isValidTime(_last_time) && _value->getTime() < _last_time) { printf("Line %zd: back in time\n", getLineNo()); return false; } size_t avail = channel->lockBuffer(*_value, _period); if (avail <= 0 || _new_ctrl_info) { channel->addBuffer(*_value, _period, _buffer_alloc); if (_buffer_alloc < MAX_VALS_PER_BUF) _buffer_alloc *= BUF_GROWTH_RATE; _new_ctrl_info = false; } channel->addValue(*_value); channel->releaseBuffer(); _last_time = _value->getTime(); return true; }
int main(int argc, const char *argv[]) { try { CmdArgParser parser(argc, argv); parser.setHeader("Archive Export version " ARCH_VERSION_TXT ", " EPICS_VERSION_STRING ", built " __DATE__ ", " __TIME__ "\n\n"); parser.setArgumentsInfo("<index file> {channel}"); CmdArgFlag be_verbose (parser, "verbose", "Verbose mode"); CmdArgString pattern (parser, "match", "<reg. exp.>", "Channel name pattern"); CmdArgFlag do_list (parser, "list", "List all channels"); CmdArgFlag do_info (parser, "info", "Time-range info on channels"); CmdArgString start_time (parser, "start", "<time>", "Format: \"mm/dd/yyyy[ hh:mm:ss[.nano-secs]]\""); CmdArgString end_time (parser, "end", "<time>", "(exclusive)"); CmdArgFlag status_text(parser, "text", "Include text column for status/severity (default)"); CmdArgFlag no_status_text(parser, "no_text", "Exclude text column for status/severity"); CmdArgString output (parser, "output", "<file>", "Output to file"); CmdArgDouble plotbin (parser, "plotbin", "<seconds>", "Bin the raw data for plotting"); CmdArgDouble average (parser, "average", "<seconds>", "average values"); CmdArgDouble linear (parser, "linear", "<seconds>", "Interpolate values linearly"); CmdArgString format_txt (parser, "format", "<decimal|engineering|exponential>", "Use specific format for numbers"); CmdArgInt prec (parser, "precision", "<int>", "Precision of numbers"); CmdArgFlag GNUPlot (parser, "gnuplot", "Generate GNUPlot command file"); CmdArgFlag image (parser, "Gnuplot", "Generate GNUPlot output for Image"); CmdArgFlag raw_time (parser, "raw_time", "Include columns for EPICS time stamp"); CmdArgFlag millisecs (parser, "millisecs", "Truncate time to millisecs in spreadsheet dump."); // defaults prec.set(-1); if (! parser.parse()) return -1; if (parser.getArguments().size() < 1) { parser.usage(); return -1; } precision = prec; if (!strncmp(format_txt.get().c_str(), "d", 1)) format = RawValue::DECIMAL; else if (!strncmp(format_txt.get().c_str(), "en", 2)) format = RawValue::ENGINEERING; else if (!strncmp(format_txt.get().c_str(), "ex", 2)) format = RawValue::EXPONENTIAL; else if (format_txt.get().length() > 0) { fprintf(stderr, "Unknown format string '%s'\n", format_txt.get().c_str()); return -1; } verbose = be_verbose; only_millisecs = millisecs; // Start/end time AutoPtr<epicsTime> start, end; stdString txt; if (start_time.get().length() > 0) { start = new epicsTime; if (!string2epicsTime(start_time.get(), *start)) { fprintf(stderr, "Parse error for start time '%s'\n", start_time.get().c_str()); start = 0; parser.usage(); return -1; } if (verbose) printf("Using start time %s\n", epicsTimeTxt(*start, txt)); } if (end_time.get().length() > 0) { end = new epicsTime(); if (!string2epicsTime(end_time.get(), *end)) { fprintf(stderr, "Parse error for end time '%s'\n", end_time.get().c_str()); end = 0; parser.usage(); return -1; } if (verbose) printf("Using end time %s\n", epicsTimeTxt(*end, txt)); } if (start && end && *start > *end) { // Could simply swap start and end, but assume the user is // confused and should rethink the request. fprintf(stderr, "start time is greater than end time.\n"); return -1; } // Index name stdString index_name = parser.getArgument(0); // Channel names stdVector<stdString> names; if (parser.getArguments().size() > 1) { if (! pattern.get().empty()) { fputs("Pattern from '-m' switch is ignored\n" "since a list of channels was also provided.\n", stderr); } // first argument was directory file name, skip that: for (size_t i=1; i<parser.getArguments().size(); ++i) names.push_back(parser.getArgument(i)); } if ((GNUPlot || image) && output.get().length() == 0) { fprintf(stderr, "The -gnuplot/Gnuplot options require " "an -output file\n"); return -1; } // How? ReaderFactory::How how = ReaderFactory::Raw; double delta = 0.0; if (double(plotbin) > 0.0) { how = ReaderFactory::Plotbin; delta = double(plotbin); } else if (double(average) > 0.0) { how = ReaderFactory::Average; delta = double(average); } else if (double(linear) > 0.0) { how = ReaderFactory::Linear; delta = double(linear); } // Open index AutoIndex index; index.open(index_name.c_str()); if (verbose) printf("Opened index '%s'\n", index_name.c_str()); if (do_info && names.size()<=0 && pattern.get().length()<=0) do_list.set(); // otherwise it'd be a NOP if (names.size() <= 0 && (do_list || pattern.get().length() > 0)) get_names_for_pattern(index, names, pattern); if (do_info) list_channels(index, names, true); else if (do_list) list_channels(index, names, false); else if (names.size() > 0) { if (GNUPlot || image) dump_gnuplot(index, names, start, end, how, delta, output, image); else dump_spreadsheet(index, names, start, end, raw_time, !no_status_text, how, delta, output); } index.close(); } catch (GenericException &e) { fprintf(stderr, "Error:\n%s\n", e.what()); return -1; } return 0; }
int main(int argc, const char *argv[]) { CmdArgParser parser(argc, argv); parser.setHeader("Archive Data Tool version " ARCH_VERSION_TXT ", " EPICS_VERSION_STRING ", built " __DATE__ ", " __TIME__ "\n\n" ); parser.setArgumentsInfo("<index-file>"); CmdArgFlag help (parser, "help", "Show help"); CmdArgInt verbosity (parser, "verbose", "<level>", "Show more info"); CmdArgFlag info (parser, "info", "Simple archive info"); CmdArgFlag list_index (parser, "list", "List channel name info"); CmdArgString copy_index (parser, "copy", "<new index>", "Copy channels"); CmdArgString start_time (parser, "start", "<time>", "Format: \"mm/dd/yyyy[ hh:mm:ss[.nano-secs]]\""); CmdArgString end_time (parser, "end", "<time>", "(exclusive)"); CmdArgDouble file_limit (parser, "file_limit", "<MB>", "File Size Limit"); CmdArgString basename (parser, "basename", "<string>", "Basename for new data files"); CmdArgFlag enforce_off (parser, "append_off", "Enforce a final 'Archive_Off' value when copying data"); CmdArgString dir2index (parser, "dir2index", "<dir. file>", "Convert old directory file to index"); CmdArgString index2dir (parser, "index2dir", "<dir. file>", "Convert index to old directory file"); CmdArgInt RTreeM (parser, "M", "<1-100>", "RTree M value"); CmdArgFlag dump_blocks (parser, "blocks", "List channel's data blocks"); CmdArgFlag all_blocks (parser, "Blocks", "List all data blocks"); CmdArgString dotindex (parser, "dotindex", "<dot filename>", "Dump contents of RTree index into dot file"); CmdArgString channel_name(parser, "channel", "<name>", "Channel name"); CmdArgFlag hashinfo (parser, "hashinfo", "Show Hash table info"); CmdArgString seek_test (parser, "seek", "<time>", "Perform seek test"); CmdArgFlag test (parser, "test", "Perform some consistency tests"); try { // Defaults RTreeM.set(50); file_limit.set(100.0); // Get Arguments if (! parser.parse()) return -1; if (help || parser.getArguments().size() != 1) { parser.usage(); return -1; } // Consistency checks if ((dump_blocks || dotindex.get().length() > 0 || seek_test.get().length() > 0) && channel_name.get().length() <= 0) { fprintf(stderr, "Options 'blocks' and 'dotindex' require 'channel'.\n"); return -1; } verbose = verbosity; stdString index_name = parser.getArgument(0); DataWriter::file_size_limit = (unsigned long)(file_limit*1024*1024); if (file_limit < 10.0) fprintf(stderr, "file_limit values under 10.0 MB are not useful\n"); // Start/end time epicsTime *start = 0, *end = 0; stdString txt; if (start_time.get().length() > 0) { start = new epicsTime; string2epicsTime(start_time.get(), *start); if (verbose > 1) printf("Using start time %s\n", epicsTimeTxt(*start, txt)); } if (end_time.get().length() > 0) { end = new epicsTime(); string2epicsTime(end_time.get(), *end); if (verbose > 1) printf("Using end time %s\n", epicsTimeTxt(*end, txt)); } // Base name if (basename.get().length() > 0) DataWriter::data_file_name_base = basename.get(); if (enforce_off) do_enforce_off = true; // What's requested? if (info) list_names(index_name, false); else if (list_index) list_names(index_name, true); else if (copy_index.get().length() > 0) { copy(index_name, copy_index, RTreeM, start, end, channel_name); return 0; } else if (hashinfo) show_hash_info(index_name); else if (dir2index.get().length() > 0) { convert_dir_index(RTreeM, dir2index, index_name); return 0; } else if (index2dir.get().length() > 0) { convert_index_dir(index_name, index2dir); return 0; } else if (all_blocks) { dump_all_datablocks(index_name); return 0; } else if (dump_blocks) { dump_datablocks(index_name, channel_name); return 0; } else if (dotindex.get().length() > 0) { dot_index(index_name, channel_name, dotindex); return 0; } else if (seek_test.get().length() > 0) { seek_time(index_name, channel_name, seek_test); return 0; } else if (test) { return check(index_name) ? 0 : -1; } else { parser.usage(); return -1; } } catch (GenericException &e) { fprintf(stderr, "Error:\n%s\n", e.what()); } return 0; }
bool MainWindow::connectToArchiver( const QString& url ) { bool connstatus = false; QDateTime curTime = QDateTime::currentDateTime(); Start_dateTime->setDateTime(QDateTime(QDate(2012,5,29), QTime(12,0,0))); End_dateTime->setDateTime(QDateTime(QDate(2012,5,29), QTime(13,0,0))); QList<CAColorTileButton*> tilepage1 = stackedWidget->widget(0)->findChildren<CAColorTileButton*>(); for( int i = 0; i < tilepage1.size();i++) { QVariant var = tilepage1.at(i)->property("pvname"); QString strpvname = var.toString(); if(strpvname.compare("pvname") == 0) continue; qDebug("Page-1->PVName[%d]:%s", i,strpvname.toStdString().c_str()); hash_tilepage1.insert(strpvname.toStdString().c_str(), tilepage1.at(i)); mpage1names.push_back(strpvname.toStdString().c_str()); }; QList<CAColorTileButton*> tilepage2 = stackedWidget->widget(1)->findChildren<CAColorTileButton*>(); for( int i = 0; i < tilepage2.size();i++) { QVariant var = tilepage2.at(i)->property("pvname"); QString strpvname = var.toString(); if(strpvname.compare("pvname") == 0) continue; qDebug("Page-2->PVName[%d]:%s", i,strpvname.toStdString().c_str()); hash_tilepage2.insert(strpvname.toStdString().c_str(), tilepage2.at(i)); mpage2names.push_back(strpvname.toStdString().c_str()); }; #if 0 epicsTime start, end; string2epicsTime(strStartTime.toStdString().c_str(), start); string2epicsTime(strEndTime.toStdString().c_str(), end); struct epicsTimeStamp epicstart_ts = (epicsTimeStamp)start; struct epicsTimeStamp epicend_ts = (epicsTimeStamp)end; double totaltime = epicsTimeDiffInSeconds( &epicend_ts, &epicstart_ts ); int timecount = (int)totaltime; #endif m_arclient.setURL(url.toStdString().c_str()); stdVector<ArchiveDataClient::ArchiveInfo> archives; connstatus = m_arclient.getArchives(archives); if (connstatus) { for (size_t i=0; i<archives.size(); ++i) { // archive list filtering... QString filtername = archives[i].name.c_str(); if(filtername.contains("PMS", Qt::CaseInsensitive) == false) continue; qDebug("Key %d: '%s' (%s)", archives[i].key, archives[i].name.c_str(), archives[i].path.c_str()); keyindex.push_back(archives[i].key); archiveList->addItem(archives[i].name.c_str()); }; }; m_arclient.setURL(url.toStdString().c_str()); //m_arclient.getValues(74, , start, end, count, how, viewer, this, interval); //m_arclient.getValues(57, mpage1names, start, end, MAX_COUNT, SHEET_TYPE, viewer, this, 1); //m_arclient.getValues(keyindex.at(archiveList->currentIndex()), mpage1names, start, end, MAX_COUNT, SHEET_TYPE, viewer, this, 1); return connstatus; }
void MainWindow::getChannelValues() { QDateTime starttime = Start_dateTime->dateTime(); QDateTime endtime = End_dateTime->dateTime(); QString strStartTime = starttime.toString("MM/dd/yyyy hh:mm:ss"); QString strEndTime = endtime.toString("MM/dd/yyyy hh:mm:ss"); #if 1 epicsTime start, end; string2epicsTime(strStartTime.toStdString().c_str(), start); string2epicsTime(strEndTime.toStdString().c_str(), end); struct epicsTimeStamp epicstart_ts = (epicsTimeStamp)start; struct epicsTimeStamp epicend_ts = (epicsTimeStamp)end; qDebug("epicsTimeStamp-Start:sec(%d), nasec(%d)", epicstart_ts.secPastEpoch, epicstart_ts.nsec); qDebug("epicsTimeStamp-End:sec(%d), nasec(%d)", epicend_ts.secPastEpoch, epicend_ts.nsec); double totaltime = epicsTimeDiffInSeconds( &epicend_ts, &epicstart_ts ); int timecount = (int)totaltime; for (size_t i = 0; i < mpage1names.size(); i++) { qDebug("PVName[%d]:%s, time:%f", i, mpage1names.at(i).c_str(), totaltime); } qDebug("KEY(%d),Start(%s), End(%s), Max(%d)", keyindex.at(archiveList->currentIndex()), strStartTime.toStdString().c_str(), strEndTime.toStdString().c_str(), MAX_COUNT); #endif mloop = 0; outstream.open("./data.txt", ios::out); // According timecount, automatically setup interval #if 1 if(CurrentPage() == 0) { vecPage1Value.clear(); vecPage1Stamp.clear(); m_arclient.getValues(keyindex.at(archiveList->currentIndex()), mpage1names, start, end, MAX_COUNT*10, SHEET_TYPE, viewer, this, 1, mloop, marraycount); } else { vecPage2Value.clear(); vecPage2Stamp.clear(); m_arclient.getValues(keyindex.at(archiveList->currentIndex()), mpage2names, start, end, MAX_COUNT*10, SHEET_TYPE, viewer, this, 1, mloop, marraycount); } #endif //Careful Array Index - Count. timeSlider->setMaximum(marraycount-1); //PVcount, Value Array Count #if 1 PVandValue *pPVValue; qDebug("LoopCount:%d, ArrayCount:%d",mloop, marraycount); for(int i = 0; i <= mloop; i++) { if(CurrentPage() == 0) { pPVValue = &(vecPage1Value.at((marraycount*i)+timeSlider->value())); qDebug("PVName[%d]:%s(%f), %s",i, pPVValue->pvname.c_str(), pPVValue->dvalue, mpage1names.at(i).c_str()); outstream << "PVName:" << pPVValue->pvname.c_str()<<"," << mpage1names.at(i).c_str() <<",PVValue: " <<pPVValue->dvalue << endl; } else { pPVValue = &(vecPage2Value.at((marraycount*i)+timeSlider->value())); qDebug("PVName[%d]:%s(%f), %s",i, pPVValue->pvname.c_str(), pPVValue->dvalue, mpage2names.at(i).c_str()); outstream << "PVName:" << pPVValue->pvname.c_str()<<"," << mpage2names.at(i).c_str() <<",PVValue: " <<pPVValue->dvalue << endl; }; }; outstream.close(); #endif timeSlider->setValue(1); }