7 Replies Latest reply on Feb 22, 2010 7:44 AM by andreas

    Cursor Trace Value

    mhalhead

      Hi,

       

      I'm writing a PB add-in in .NET and one of the items I need is the trace value at a cursor. To example a bit more; The user creates two or more cursors and then from two comboboxes (in a docked window) selects the cursors of interest. The add-in then calculates the differences between the two cursors (time difference, value difference); I plan to use PI summaries2 to calculate the statistics between the time range as a later enhancement. However, the first problem I need to solve is how to get the trace value at a cursor/time. I would rather not use a PISDK call to get the value as this will not work for datasets.

        • Re: Cursor Trace Value

          Do you mean something along the lines of:

          
          

          Dim T As Trend
          Set T = Trend1
          For i = 1 To T.CursorCount
              T.CurrentCursor = i
             
              Debug.Print T.CursorTime
              For j = 1 To T.TraceCount
                  Dim vStat As Variant
                  T.CurrentTrace = j
                  Debug.Print T.GetValue(T.CursorTime, vStat)
              Next j
             
          Next i
          Set T = Nothing

           

          Above is VBA but you get the idea.

           

          Get a Trend Object, identify which cursor and trace then get the trace value for the cursor time.

            • Re: Cursor Trace Value

              I don't know what else your PI ProcessBook add-in does, but you might want to leverage the "Tooltip Statistics" functionality - a built-in feature in PI ProcessBook. Simply hover the mouse over a trace on a trend, and you'll see standard statistics appear.

               

              The "range" (value in difference) doesn't show up? Just go Tools > ToolTip Statistics... and check the Range option.

               

              Want to isolate to a specific range on the trend (i.e. select 2 values)? Just zoom in on the trend such that you have the desired values at the boundaries of the trend graph.

               

              Maybe I'm oversimplifying your requirements, but I thought it couldn't hurt to know a little more about built-in features

                • Re: Cursor Trace Value

                  @Michael Halhead: did you get that one sorted out?

                   

                  It seems like somebody else is interested in doing the same (see this other post) - I'm sure he'd be interested to know what you ended up doing and what difficulties, if any, you came across.

                    • Re: Cursor Trace Value
                      mhalhead

                      Thanks Steve and Rhys,

                       

                      To be honest I never got the GetValue to work correctly; for some reason I also get the values at the end of the trend. I haven't pursued it (a challenge for later) as I've gone the route of using the PI-SDK summaries2 method as this returns a range along with along with a bunch of other useful statistics. I will read through the other post. I have no real objection to posting the source code for this add-in; firstly I will need to choose a suitable license (it would be better if people contribute to the solution) and secondly I need to cleanup the code quite considerably (it a touch mess shall we say and I haven't handled all the events) I will try and get this done next week (I do this sort of thing as night and on weekends). This brings me to the obvious question what is the deal with posting add-in? Do I simply add it to a post?

                        • Re: Cursor Trace Value
                          andreas

                          Hi Michael,

                           

                          The GetValue does return the latest value on the trend. So you would have to go for the PISDK in this case. Below is a code snippet from a small addin reading all the values at the cursors and populating a listview:

                          PBObjLib.Symbols _MySymbols;
                          try
                          {
                              _MySymbols = m_app.ActiveDisplay.Symbols;
                          }
                          catch (Exception _ex)
                          {
                              this.textBox1.Text = _ex.ToString();
                              return;
                          }

                          listView1.Clear();

                          foreach
                          (PBObjLib.Symbol _MySymbol in _MySymbols)
                          {
                              if (_MySymbol.Type == 10) {
                                  PBSymLib.Trend _MyTrend;
                                  _MyTrend = (PBSymLib.Trend)_MySymbol;
                                  if (_MyTrend.CursorCount > 0)
                                  {
                                      // Create the Columns
                                      listView1.Columns.Add("Tagname");
                                      for (short _sc = 1; _sc <= _MyTrend.CursorCount; _sc++)
                                      {
                                          _MyTrend.CurrentCursor = _sc;
                                          listView1.Columns.Add(_MyTrend.CursorTime.ToString());
                                      }

                                      ListViewItem[] _lvi;
                                      _lvi = newListViewItem[_MyTrend.TraceCount];

                                      // Create the ListView items
                                      for (short _st = 1; _st <= _MyTrend.TraceCount; _st++)
                                      {
                                          _lvi[_st - 1] = newListViewItem(_MyTrend.GetTagName(_st));
                                      }

                                      // Get the PIValues with PISDK
                                      for (short _sc = 1; _sc <= _MyTrend.CursorCount; _sc++)
                                      {
                                          _MyTrend.CurrentCursor = _sc;

                                          for (short _st = 1; _st <= _MyTrend.TraceCount; _st++)
                                          {
                                              string[] str = _MyTrend.GetTagName(_st).Split('\\');
                                              PISDK.PIValue _PIValue;
                                              _PIValue = _PISDK.Servers[str[2]].PIPoints[str[3]].Data.ArcValue(_MyTrend.CursorTime,
                                                                 PISDK.RetrievalTypeConstants.rtInterpolated,
                                                                 null);
                                              _lvi[_st - 1].SubItems.Add(_PIValue.Value.ToString());
                                          }
                                      }

                                      // Add the Items to the ListView
                                      for (short _st = 1; _st <= _MyTrend.TraceCount; _st++)
                                      {
                                          this.listView1.Items.Add(_lvi[_st - 1]);
                                      }
                                  }
                              }
                          }

                          Hope this helps

                            • Re: Cursor Trace Value
                              mhalhead

                              Thanks Andreas for the rather comprehensive example. One question how would you handle data sets on the trend? I haven't tested a dataset yet but I'm assuming that the PI SDK would throw and error.

                                • Re: Cursor Trace Value
                                  andreas

                                  yeah  - a dataset would be different. Haven't had a chance to play around with datasets yet, but my aproach would be, get the PE and let the PISDK.IPICalculation calculate the result. Alternatively you may retrieve the plot values from the trend and select the right one by yourself (should be easy for a steped plot).