Changeset 159 for Evidence/Edd


Ignore:
Timestamp:
02/04/10 15:26:55 (15 years ago)
Author:
ogrimm
Message:
Change in history handling
Location:
Evidence/Edd
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Evidence/Edd/Edd.cc

    r154 r159  
    99a DIM status service
    1010
    11 December 2009, Oliver Grimm
     11February 2010, Oliver Grimm
    1212
    1313============================================================ */
     
    3535 
    3636  // Connect to DIM handler
    37   if (connect(Handler, SIGNAL(YEP(DimInfo*, int, QString, QByteArray, QString)), SLOT(Update(DimInfo*, int, QString, QByteArray, QString))) == false) {
     37  if (connect(Handler, SIGNAL(YEP(DimInfo*, int, QByteArray, QString)), SLOT(Update(DimInfo*, int, QByteArray, QString))) == false) {
    3838    printf("Failed connection for %s\n", DIMService.toAscii().data());
    3939  }
     
    4343  Menu->addAction("Open history", this, SLOT(MenuOpenHistory()));
    4444  Menu->addAction("Copy service", this, SLOT(MenuCopyService()));
     45  Menu->addAction("Copy data", this, SLOT(MenuCopyData()));
    4546
    4647  // DIM client
    47   Data = new DimStampedInfo(DIMService.toAscii().data(), INT_MAX, (char *) NO_LINK, Handler);
     48  Data = new DimStampedInfo(DIMService.toAscii().data(), INT_MAX, NO_LINK, Handler);
    4849}
    4950
     
    5455
    5556// Update widget
    56 void Edd_Indicator::Update(DimInfo *Info, int Time, QString Format, QByteArray Data, QString Text) {
    57 
    58   if (Info != this->Data) return;
     57void Edd_Indicator::Update(DimInfo *Info, int Time, QByteArray Array, QString Text) {
     58
     59  if (Info != Data) return;
    5960   
    6061  QPalette Pal = palette(); 
     
    6768  }
    6869  else {
    69     // If this is a status indicator, adapt background colour
    70     if (Data.size() == Text.size()+2) {
    71       switch (Data[Text.size() + 1]) {
    72         case 0:  Pal.setColor(QPalette::Base, Qt::white); break;
    73         case 1:  Pal.setColor(QPalette::Base, Qt::yellow); break;
    74         case 2:  Pal.setColor(QPalette::Base, Qt::red); break;
    75         case 3:  Pal.setColor(QPalette::Base, Qt::red); break;
    76         default: break;
    77       }
     70    // Backgound colour determined by last byte
     71    switch (Array[Array.size()]) {
     72      case 0:  Pal.setColor(QPalette::Base, Qt::white); break;
     73      case 1:  Pal.setColor(QPalette::Base, Qt::yellow); break;
     74      case 2:  Pal.setColor(QPalette::Base, Qt::red); break;
     75      case 3:  Pal.setColor(QPalette::Base, Qt::red); break;
     76      default: break;
    7877    }
    79     else Pal.setColor(QPalette::Base, Qt::white);
    8078       
    8179        if (!ShowAsTime) setText(Text);
     
    8381       
    8482    // Update status tip
    85     setStatusTip(QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), QDateTime::fromTime_t(Time).toString()).arg(Format));
     83    setStatusTip(QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), QDateTime::fromTime_t(Time).toString()).arg(Info->getFormat()));
    8684  }
    8785 
     
    134132}
    135133
    136 // Open history plot
     134// Menu: Open history plot
    137135void Edd_Indicator::MenuOpenHistory() {
    138136 
     
    141139}
    142140
    143 // Copy service name
     141// Menu: Copy service name
    144142void Edd_Indicator::MenuCopyService() {
    145143 
    146144  QApplication::clipboard()->setText(QString(Data->getName()));
     145}
     146
     147// Menu: Copy data
     148void Edd_Indicator::MenuCopyData() {
     149 
     150  QApplication::clipboard()->setText(text());
    147151}
    148152
     
    154158// Constructor
    155159//
    156 Edd_Plot::Edd_Plot(QString DIMService, QWidget *P): QwtPlot(P) {
     160Edd_Plot::Edd_Plot(QString DIMService, QWidget *P): QwtPlot(P), EvidenceHistory() {
    157161
    158162  setAcceptDrops(true);
     
    180184 
    181185  // Connect to DIM handler
    182   if (connect(Handler, SIGNAL(YEP(DimInfo *, int, QString, QByteArray, QString)), SLOT(Update(DimInfo *, int, QString, QByteArray, QString))) == false) {
     186  if (connect(Handler, SIGNAL(YEP(DimInfo *, int, QByteArray, QString)), SLOT(Update(DimInfo *, int, QByteArray, QString))) == false) {
    183187    printf("Failed connection for %s\n", DIMService.toAscii().data());
    184188  }
     
    211215
    212216  for (int i=0; i<Items.size(); i++) {
    213     delete Items[i].Data;
    214217    delete Items[i].LiveData;
    215218    delete Items[i].Signal;
    216     delete[] Items[i].x;
    217     delete[] Items[i].y;
    218219  } 
    219220  delete Grid;
     
    225226void Edd_Plot::AddService(QString Name) {
    226227
    227   QString HistName = Name+".hist";
    228 
    229228  // Lock before accessing Items list
    230229  QMutexLocker Locker(&Mutex);
    231230
    232   // Check if already subsribed to service
     231  // Check if already subscribed to service
    233232  for (int i=0; i<Items.size(); i++) {
    234     if (HistName == Items[i].Data->getName()) {
    235       QMessageBox::warning(this, "Edd Message",HistName+" already present",QMessageBox::Ok);
     233    if (Name == Items[i].LiveData->getName()) {
     234      QMessageBox::warning(this, "Edd Message",Name+".hist already present",QMessageBox::Ok);
    236235      return;
    237236    }
     
    242241  New.Signal = new QwtPlotCurve;
    243242  New.Signal->attach(this);
    244   New.Signal->setTitle(HistName);
     243  New.Signal->setTitle(Name+".hist");
    245244  New.Signal->setPen(QColor(LineColors[Items.size() % (sizeof(LineColors)/sizeof(Qt::GlobalColor))]));
    246   New.x = NULL;
    247   New.y = NULL;
    248   New.Count = 0;
    249   New.Data = new DimStampedInfo(HistName.toAscii().data(), (char *) NO_LINK, Handler);
    250   New.LiveData = new DimStampedInfo(Name.toAscii().data(), (char *) NO_LINK, Handler);
     245  New.SizeLimit = 5000;
     246  New.LiveData = new DimStampedInfo(Name.toAscii().data(), NO_LINK, Handler);
    251247
    252248  Items.append(New);
     
    254250
    255251// Update widget (must happen in GUI thread)
    256 void Edd_Plot::Update(DimInfo *Info, int Time, QString Format, QByteArray Data, QString Text) {
     252void Edd_Plot::Update(DimInfo *Info, int Time, QByteArray, QString Text) {
    257253
    258254  // Check if service available
     
    266262  // Determine which plot item this call belongs to
    267263  int ItemNo;
    268   for (ItemNo=0; ItemNo<Items.size(); ItemNo++) if (Info == Items[ItemNo].Data) {
    269     // This is a history service 
    270     EvidenceHistoryItem *Curr = (EvidenceHistoryItem *) Data.data();
    271     int Count=0, DataPoints = Data.size()/sizeof(struct EvidenceHistoryItem);
    272 
    273     delete[] Items[ItemNo].x;
    274     delete[] Items[ItemNo].y;
    275     Items[ItemNo].x = new int [DataPoints];
    276     Items[ItemNo].y = new double [DataPoints];
    277 
    278     // Find oldest item
    279     int Oldest;
    280     for (Oldest=1; Oldest<DataPoints; Oldest++) {
    281       if (Curr[Oldest].Seconds < Curr[Oldest-1].Seconds) break;
     264  for (ItemNo=0; ItemNo<Items.size(); ItemNo++) if (Info == Items[ItemNo].LiveData) {
     265 
     266        // If size limit reached, clear buffer
     267    if (Items[ItemNo].x.size() > Items[ItemNo].SizeLimit) {
     268          Items[ItemNo].x.clear();
     269          Items[ItemNo].y.clear();
    282270    }
    283271
    284     // Plot data starting with oldest value
    285     for (int i=0; i<DataPoints; i++) {
    286       Items[ItemNo].x[Count] = Curr[(i+Oldest)%DataPoints].Seconds;
    287       Items[ItemNo].y[Count] = Curr[(i+Oldest)%DataPoints].Value;
    288       if (Items[ItemNo].x[Count] != 0) Count++;
    289     }
    290 
    291     // Find smallest and largest item
    292     double Smallest = DBL_MAX, Largest = DBL_MIN;
    293     for (int i=0; i<Count; i++) {
    294       if (Largest < Items[ItemNo].y[i]) Largest = Items[ItemNo].y[i];
    295       if (Smallest > Items[ItemNo].y[i]) Smallest = Items[ItemNo].y[i];
    296     }
    297     Items[ItemNo].Smallest = Smallest;
    298     Items[ItemNo].Largest = Largest;
    299     Items[ItemNo].Count = Count;
    300 
    301     // Clear local history
    302     Items[ItemNo].Live.clear();
     272        // If buffer empty, request new history buffer
     273    if (Items[ItemNo].x.isEmpty()) {
     274          int Time, Size;
     275          void *Data;
     276
     277          if (GetHistory(Items[ItemNo].LiveData->getName())) {
     278        double Smallest = DBL_MAX, Largest = DBL_MIN;
     279                double Number=0;
     280                while (Next(Time, Size, Data)) {
     281                  switch (*(Info->getFormat())) {
     282                case 'I':  Number = *(int *) Data;   break;
     283                case 'S':  Number = *(short *) Data;   break;
     284                case 'F':  Number = *(float *) Data;   break;
     285                case 'D':  Number = *(double *) Data;   break;
     286                case 'X':  Number = *(long long *) Data;   break;
     287                default: break;
     288                  }
     289
     290                  Items[ItemNo].x.append(Time);
     291                  Items[ItemNo].y.append(Number);
     292                 
     293          if (Largest < Items[ItemNo].y.last()) Largest = Items[ItemNo].y.last();
     294          if (Smallest > Items[ItemNo].y.last()) Smallest = Items[ItemNo].y.last();
     295                }
     296
     297        Items[ItemNo].Smallest = Smallest;
     298        Items[ItemNo].Largest = Largest;
     299
     300                // Local buffer always at least twice as large as history
     301                if (Items[ItemNo].SizeLimit < 2*Items[ItemNo].x.size()) {
     302                  Items[ItemNo].SizeLimit = 2*Items[ItemNo].x.size();
     303                }               
     304          }
     305        }
     306
     307    // Append data
     308    Items[ItemNo].x.append(Time);
     309    Items[ItemNo].y.append(atof(Text.toAscii().data()));
     310
     311    // Update largest and smallest value   
     312    if (Items[ItemNo].y.last() > Items[ItemNo].Largest) Items[ItemNo].Largest = Items[ItemNo].y.last();
     313    if (Items[ItemNo].y.last() < Items[ItemNo].Smallest) Items[ItemNo].Smallest = Items[ItemNo].y.last();   
    303314
    304315    // Update status tip
    305316    QDateTime Timex = QDateTime::fromTime_t(Time);
    306     StatusTip = QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), Timex.toString()).arg(Format);
    307 
    308   } else if (Info == Items[ItemNo].LiveData) {
    309     // This is a live service
    310 
    311     // Limit size of list
    312     if (Items[ItemNo].Live.size() > 1000) Items[ItemNo].Live.removeFirst();
    313 
    314     // Append data
    315     struct EvidenceHistoryItem Data;
    316     Data.Seconds = Time;
    317     Data.Value = atof(Text.toAscii().data());           
    318     Items[ItemNo].Live.append(Data);
    319 
    320     // Update largest and smallest value   
    321     if (Data.Value > Items[ItemNo].Largest) Items[ItemNo].Largest = Data.Value;
    322     if (Data.Value < Items[ItemNo].Smallest) Items[ItemNo].Smallest = Data.Value;   
     317    StatusTip = QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), Timex.toString()).arg(Info->getFormat());
    323318  }
    324319
     
    352347    else Items[ItemNo].Signal->setSymbol(Sym1);
    353348
    354     int DataPoints = Items[ItemNo].Count + Items[ItemNo].Live.size();
     349    int DataPoints = Items[ItemNo].x.size();
    355350       
    356351        if (DataPoints == 0) continue;
     
    361356    // Adapt time scale and normalize y scale if requested
    362357    for (int i=0; i<DataPoints; i++) {
    363       if (i < Items[ItemNo].Count) {
    364         x[i] = Items[ItemNo].x[i] / 86400.0 + 40587.5 - 55200;
    365         y[i] = Items[ItemNo].y[i];
    366       }
    367       else {
    368         x[i]= Items[ItemNo].Live[i-Items[ItemNo].Count].Seconds / 86400.0 + 40587.5 - 55200;
    369         y[i] = Items[ItemNo].Live[i-Items[ItemNo].Count].Value;
    370       }
     358      x[i] = Items[ItemNo].x[i] / 86400.0 + 40587.5 - 55200;
     359      y[i] = Items[ItemNo].y[i];
    371360
    372361      if (NormAction->isChecked()) {
    373         if (Items[ItemNo].Smallest != Items[ItemNo].Largest) y[i] = (y[i] - Items[ItemNo].Smallest)/(Items[ItemNo].Largest-Items[ItemNo].Smallest);
    374         else y[i] = 1;
     362            if (Items[ItemNo].Smallest != Items[ItemNo].Largest) {
     363                  y[i] = (y[i] - Items[ItemNo].Smallest)/(Items[ItemNo].Largest-Items[ItemNo].Smallest);
     364                }
     365            else y[i] = 1;
    375366      } 
    376367    }
    377368
    378     // Plot datas
     369    // Plot data
    379370    Items[ItemNo].Signal->setData(x, y, DataPoints);
    380371    Items[ItemNo].Signal->show();
     
    443434
    444435  while (Items.size() > 1) { 
    445     delete Items.last().Data;
    446436    delete Items.last().LiveData;
    447437    delete Items.last().Signal;
    448     delete[] Items.last().x;
    449     delete[] Items.last().y;
    450438    Items.takeLast();
    451439  }
     
    473461   // Write x and y data for all signals to file
    474462  for (int ItemNo=0; ItemNo<Items.size(); ItemNo++) {
    475     Stream << QString("# ")+Items[ItemNo].Data->getName() << endl;
     463    Stream << QString("# ")+Items[ItemNo].LiveData->getName()+".hist" << endl;
    476464    for (int i=0; i<Items[ItemNo].Signal->dataSize(); i++) {
    477       Stream << (int) Items[ItemNo].x[i] << " " << Items[ItemNo].Signal->y(i) << endl;
     465      Stream << (int) Items[ItemNo].x.at(i) << " " << Items[ItemNo].Signal->y(i) << endl;
    478466    }
    479467  }
     
    514502
    515503
     504///////////////////////////////////////
     505// History text box for DIM service //
     506//////////////////////////////////////
     507
     508//
     509// Constructor
     510//
     511Edd_TextHist::Edd_TextHist(QString DIMService, QWidget *P): QTextEdit(P), EvidenceHistory() {
     512 
     513  // Widget properties
     514  setReadOnly(true);
     515  setAttribute(Qt::WA_DeleteOnClose);
     516  setAutoFillBackground(true);
     517  document()->setMaximumBlockCount(1000);
     518 
     519  // Connect to DIM handler
     520  if (connect(Handler, SIGNAL(YEP(DimInfo*, int, QByteArray, QString)), SLOT(Update(DimInfo*, int, QByteArray, QString))) == false) {
     521    printf("Failed connection for %s\n", DIMService.toAscii().data());
     522  }
     523
     524  // Get history for this service
     525  int Time, Size;
     526  void *Data;
     527
     528  if (GetHistory(DIMService.toAscii().data())) {
     529        while (Next(Time, Size, Data)) {
     530          moveCursor (QTextCursor::Start);
     531          insertPlainText(QString("(")+QDateTime::fromTime_t(Time).toString()+") ");     
     532          insertPlainText(QString((char *) Data) + "\n");         
     533        }
     534  }
     535
     536  // DIM client
     537  Service = new DimStampedInfo(DIMService.toAscii().data(), INT_MAX, NO_LINK, Handler);
     538}
     539
     540// Destructor
     541Edd_TextHist::~Edd_TextHist() {
     542
     543  delete Service;
     544}
     545
     546
     547// Update widget (must happen in GUI thread)
     548void Edd_TextHist::Update(DimInfo *Info, int Time, QByteArray, QString Text) {
     549
     550  if (Info != this->Service) return;
     551
     552  // Check if service available
     553  if (Time == -1) {
     554        setStatusTip(QString("%1:  unavailable").arg(Info->getName()));
     555        return;
     556  }
     557
     558  QDateTime Timex = QDateTime::fromTime_t(Time);
     559
     560  moveCursor(QTextCursor::Start);
     561  insertPlainText(QString("(")+Timex.toString()+QString(") "));   
     562  insertPlainText(Text + "\n");   
     563       
     564  // Update status tip
     565  StatusTip = QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), Timex.toString()).arg(Info->getFormat());
     566}
     567
     568
    516569//////////////////
    517570// Text display //
     
    528581 
    529582  // Connect to DIM handler
    530   if (connect(Handler, SIGNAL(YEP(DimInfo*, int, QString, QByteArray, QString)), SLOT(Update(DimInfo*, int, QString, QByteArray, QString))) == false) {
     583  if (connect(Handler, SIGNAL(YEP(DimInfo*, int, QByteArray, QString)), SLOT(Update(DimInfo*, int, QByteArray, QString))) == false) {
    531584    printf("Failed connection for %s\n", DIMService.toAscii().data());
    532585  }
    533586
    534587  // DIM client
    535   Data = new DimStampedInfo(DIMService.toAscii().data(), INT_MAX, (char *) NO_LINK, Handler);
     588  Data = new DimStampedInfo(DIMService.toAscii().data(), INT_MAX, NO_LINK, Handler);
    536589}
    537590
     
    543596
    544597// Handling of DIM service update
    545 void Edd_Textout::Update(DimInfo *Info, int Time, QString Format, QByteArray, QString Text) {
     598void Edd_Textout::Update(DimInfo *Info, int Time, QByteArray, QString Text) {
    546599
    547600  if (Info != this->Data) return;
     
    561614       
    562615    // Add if service contains only a string
    563     if (Format == "C") insertPlainText(Text);
     616    if (strcmp(Info->getFormat(), "C") == 0) insertPlainText(Text);
    564617
    565618    // Update status tip
    566     setStatusTip(QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), QDateTime::fromTime_t(Time).toString()).arg(Format));
     619    setStatusTip(QString("%1:  Last update %2  Format '%3'").arg(Info->getName(), QDateTime::fromTime_t(Time).toString()).arg(Info->getFormat()));
    567620  }
    568621  setPalette(Pal);
     
    652705  MainLayout->addWidget(Value, 7, 0, 1, 1);
    653706
     707  QPushButton *Button = new QPushButton();
     708  Button->setText("Start DIM browser");
     709  connect(Button, SIGNAL(released()), SLOT(StartDIMBrowser()));
     710  MainLayout->addWidget(Button, 7, 1, 1, 1);
     711
     712  Edd_TextHist *Bla;
     713  Bla = new Edd_TextHist("DColl/CurrentFile");
     714  MainLayout->addWidget(Bla, 8, 0, 1, 1);
    654715
    655716  // Layout of all widgets
     
    669730    Text = Text.sprintf("Bias/VOLT/ID00/00-%.3d",i);
    670731    Value = new Edd_Indicator(Text);
     732
    671733    BiasLayout->addWidget(Value, i%9+1, 0+i/9, 1, 1);
    672734    Graph->AddService(Text);
     
    686748  Textout->setFixedWidth(400);
    687749  BiasLayout->addWidget(Textout, 10, 0, 4, 4);     
    688  
     750
    689751  // Environment page
    690752  EnvironmentWidget = new QWidget();
     
    772834
    773835  // Check if service available
    774   if (getInfo()->getSize() == strlen(NO_LINK)+1 && strcmp(getInfo()->getString(), NO_LINK) == 0) {
    775     YEP(getInfo(), -1);
    776   }
     836  if (!EvidenceServer::ServiceOK(getInfo())) YEP(getInfo(), -1);
    777837  else {
    778838    char *Txt = EvidenceServer::ToString(getInfo());
    779839
    780     YEP(getInfo(), getInfo()->getTimestamp(), getInfo()->getFormat(), QByteArray((char *) getInfo()->getData(), getInfo()->getSize()), QString(Txt));
    781                 free(Txt);
    782   }
    783 }
     840    YEP(getInfo(), getInfo()->getTimestamp(), QByteArray((char *) getInfo()->getData(), getInfo()->getSize()), QString(Txt));
     841        free(Txt);
     842  }
     843}
     844
     845// Start DIM Browser
     846void GUI::StartDIMBrowser() {
     847
     848  QProcess::startDetached("did", QStringList(), QString(getenv("DIMDIR"))+"/linux/");
     849}
     850
    784851
    785852//---------------------------------------------------------------------
  • Evidence/Edd/Edd.h

    r152 r159  
    4646       
    4747  private slots:
    48         void Update(DimInfo *, int, QString, QByteArray, QString);
     48        void Update(DimInfo *, int, QByteArray, QString);
    4949    void contextMenuEvent(QContextMenuEvent *);   
    5050    void MenuOpenHistory();
    5151    void MenuCopyService();
     52    void MenuCopyData();
    5253};
    5354
    5455// Graph class for history display
    55 class Edd_Plot: public QwtPlot, public DimClient {
     56class Edd_Plot: public QwtPlot, public EvidenceHistory {
    5657    Q_OBJECT
    5758
    5859    struct PlotItem {
    59       DimInfo *Data;
    6060      DimInfo *LiveData;
    6161      QwtPlotCurve *Signal;
    62       int *x;
    63       double *y;
    64       int Count;
    6562      double Smallest;
    6663      double Largest;
    67       QList<struct EvidenceHistoryItem> Live;
     64          int SizeLimit;
     65          QVector<double> x;
     66          QVector<double> y;     
    6867    };
    6968
     
    9392  private slots:
    9493    void UpdatePlot();
    95         void Update(DimInfo* Info, int, QString, QByteArray, QString);
     94        void Update(DimInfo* Info, int, QByteArray, QString);
    9695
    9796    void HandleZoom(const QwtDoubleRect &);
     
    106105};
    107106
     107// Text history class
     108class Edd_TextHist: public QTextEdit, public EvidenceHistory {
     109    Q_OBJECT
     110
     111        QString StatusTip;
     112        DimStampedInfo *Service;
     113       
     114  public:
     115    Edd_TextHist(QString, QWidget * = NULL);
     116    ~Edd_TextHist();
     117
     118  private slots:
     119        void Update(DimInfo* Info, int, QByteArray, QString);
     120};
     121
    108122// Textout indicator for DIM service
    109 class Edd_Textout: public QTextEdit, public DimClient {
     123class Edd_Textout: public QTextEdit, public EvidenceHistory {
    110124    Q_OBJECT
    111125
     
    119133       
    120134  private slots:
    121         void Update(DimInfo* Info, int, QString, QByteArray, QString);
     135        void Update(DimInfo* Info, int, QByteArray, QString);
    122136};
    123137
     
    143157    void MenuAbout();
    144158    void MenuNewHistory();
     159        void StartDIMBrowser();
    145160       
    146161  signals:
    147     void YEP(DimInfo *, int, QString = QString(), QByteArray = QByteArray(), QString = QString());
     162    void YEP(DimInfo *, int, QByteArray = QByteArray(), QString = QString());
    148163};
    149164
Note: See TracChangeset for help on using the changeset viewer.