17 Replies Latest reply on Oct 21, 2010 10:23 PM by charlie@osisoft.com

    PI Event Time

    aladams

      I am trying to capture the PI Event Time that is seen in the PI System Management Tools Archive Editor.  I need the date/time down to the sub-seconds.  When I run the following code I only get down to the seconds and this is causing me problems when there are more than one recording down to the second. Is there a way to capture the sub-seconds? 

      Dim rttype As RetrievalTypeConstants    'retrieval type = atorbefore

      Dim dtLateDate As Date                  'late date/time

      Dim pt As PIPoint                       'pi point
      Dim pv As PIValue                       'archive value
      Dim ptlist As PointList                 'pi point list

      dtLateDate = ThisDisplay.dtpLateDate + ThisDisplay.dtpLateTime

      For Each pt In ptlist
              Set pv = pt.Data.ArcValue(dtLateDate, rttype)

             'from here I use the pv.Value and pv.TimeStamp.LocalDate

      PI Data

      Value               Event Time

      Non-Update      8/25/2010 7:44:37.47011 PM

       

      533.3333         8/25/2010 7:44:37.97011 PM

        • Re: PI Event Time
          Ahmad Fattahi

          It is most likely because of the way you "show" teh time and not the way you retrieve or store it. Here is a code snippet that populates a list box with the timestamp fo an event in three different ways. It clearly shows that the difference is in the way we represent data (Thanks to Harry Smith):

          Private Sub Command1_Click()
              Dim srv As Server
              Set srv = Servers("ohio")
              Dim pt As PIPoint
              Set pt = srv.PIPoints.Item("01:sdktst.01")
              Dim dat As PIData
              Set dat = pt.Data
              Dim pv As PIValue
              Set pv = dat.Snapshot
              List1.AddItem CStr(pv.TimeStamp.UTCSeconds)
              List1.AddItem CStr(pv.TimeStamp.LocalDate)
              List1.AddItem CStr(CDbl(pv.TimeStamp.LocalDate))
          End Sub

          So you can see the UTCSeconds show my fraction to roughly 15 significant digits (it's a double - seconds since 1970).

           

          The LocalDate when printed as a string rounds off to the nearest second.

           

          The same property when printed as a float shows a decimal number of days.

           

          Conclusion is it is just the way you are displaying the time ... the subseconds have been captured.  If you want to display subseconds in a string, take a look at the PITimeFormat object and its FormatString property.

           

          Subsecond.jpg

            • Re: PI Event Time
              aladams

              I have searched pisdk.help for PITimeFormat and found the definition for it.  Is there somewhere I can get an example using the PITimeFormat so that my end result/output is 8/30/2010 5:13:10.xxx PM. and I can display/use down to the subseconds?

                • Re: PI Event Time
                  Ahmad Fattahi

                  You can try a few options here.

                   

                  For one thing you can use PITimeFormat object. You can take a look at the “FormatString” property as well as “LocalDate” property. The former allows you to format the output string while the latter matches the format to what you have used on your OS.

                   

                  The other direction you might want to look is using .NET formatting capabilities outside PI-SDK. In particular take a look at .NET DateTime objct.

                  • Re: PI Event Time
                    richs04

                    If you set the PITimeFormat.FormatString = "M/d/yyyy h:m:ss.000 AP" you should get your desired results.

                      • Re: PI Event Time
                        aladams

                        Wow am I really struggling with something that is probably extremely simple.  So if I go back to my original code would I place the PITimeFormat.FormatString on pv so that when I ask for the LocalDate it will pick up the subseconds using the FormatString?  I tried placing it on pv but I don't pick it up as a property and also can't figure out how the syntax should be.  Sorry I think I keep asking the same question maybe the third time is the charm.

                        Dim rttype As RetrievalTypeConstants    'retrieval type = atorbefore

                        Dim dtLateDate As Date                  'late date/time

                        Dim pt As PIPoint                       'pi point
                        Dim pv As PIValue                       'archive value
                        Dim ptlist As PointList                 'pi point list

                        dtLateDate = ThisDisplay.dtpLateDate + ThisDisplay.dtpLateTime

                        For Each pt In ptlist
                                Set pv = pt.Data.ArcValue(dtLateDate, rttype)

                               'from here I use the pv.Value and pv.TimeStamp.LocalDate

                          • Re: PI Event Time
                            richs04

                            Try this in your code. I'msure there are shorter ways to get the date string but this should work.

                             

                            C# code:

                             

                             

                             

                             

                             

                             

                             

                            PITimeServer.PITimeFormat ts = new PITimeServer.PITimeFormat; 
                            ts.LocalDate = pv.TimeStamp.LocalDate;
                            ts.FormatString = "M/dd/yyyy h:mm:ss.0000";
                            string s = ts.OutputString();

                              • Re: PI Event Time

                                Just in case here is Richard's (C#) code, converted to VBA (I take it that you are in PI ProcessBook VBA, from your references to ThisDisplay):

                                Dim ts As New PITimeServer.PITimeFormat
                                ts.LocalDate = pv.TimeStamp.LocalDate
                                ts.FormatString = "M/dd/yyyy h:mm:ss.0000"
                                Dim s As String
                                s = ts.OutputString

                                Also, note that you need a reference to the PITimeServer library (Tools > References)... this is the class library that PITimeFormat is part of.

                                  • Re: PI Event Time
                                    aladams

                                    Thank you guys I am halfway there!  I added the code to capture the outputstring that included the subseconds.  Now I need to put the outputstring back in the code to get the next local date.  This part isn't working.  Perhaps you can't use the outputstring in the ArcValue.  If I'm reading the help correctly it says it takes a date/time string.  Here's my code:

                                    Dim rttype as RetrievalTypeConstants                  'retrieval type = atorbefore
                                    Dim pt as PiPoint
                                    Dim pv as PiValue
                                    Dim dtEarlyDate as Date
                                    'Variables to handle subseconds
                                    Dim ts as New PITimeServer.PITimeFormat
                                    ts.FormatString = "M/d/yyyy h:mm:ss.00000 AP"
                                    Dim sOutPut as String
                                    dtEarlyDate = ThisDisplay.dtEarlyDate + ThisDisplay.dtEarlyTime
                                    set pv = pt.Data.ArcValue(dtEarlyDate, rttype)
                                    ts.LocalDate = pv.TimeStamp.LocalDate
                                    sOutPut = ts.OutPutString                             'value = 8/12/2010 11:56:09.77011 PM

                                    ----ALL OF THAT ABOVE WORKS GREAT!  I loop through some processing and now I need to get the next Event Time

                                     

                                    set pv = pt.Data.ArcValue(sOutPut, rttype)
                                    ts.LocalDate = pv.TimeStamp.LocalDate
                                    sOutPut = ts.OutPutString
                                    ----THIS DOESN'T WORK.  I even changed the datatype for sOutPut to CDate and that didn't help.  Doesn't seem to budge from original value of

                                     

                                         8/12/2010 11:56:09.77011 PM

                                      • Re: PI Event Time
                                        andreas

                                        How is your rttype set? ArcValue does accept the string - that is not the problem, but if you set rttype for example to rtAtOrBefore you will always get the same value. You should use either rtAfter or rtBefore.

                                          • Re: PI Event Time

                                            @Lynn: just curious, did Andreas' suggestion help address your problem? Do you need further assistance with this?

                                              • Re: PI Event Time
                                                aladams

                                                Actually I do need further assistance. I am able to figure out how to get the subseconds, but now I can't seem to move past the ones that are identical down to the seconds.  My example is below.  Seems to move thru the data fine until it hits the identical seconds.  Any ideas?


                                                Set pv = pt.Data.ArcValue(dtRequested, rtAtorBefore)    'dtRequested = 8/10/2010 7:37:00 AM
                                                ts.LocalDate = pv.TimeStamp.LocalDate                   'subseconds
                                                sOutPut = ts.OutputString                               'sOutPut = 8/10/2010 7:36:31.0601 AM

                                                Set pv = pt.Data.ArcValue(sOutPut, rtBefore)            'sOutPut = 8/10/2010 7:36:31.0601 AM
                                                ts.LocalDate = pv.TimeStamp.LocalDate                   'subseconds
                                                sOutPut = ts.OutputString                               'sOutPut = 8/10/2010 7:35:52.30011 AM

                                                Set pv = pt.Data.ArcValue(sOutPut, rtBefore)            'sOutPut = 8/10/2010 7:35:52.30011 AM
                                                ts.LocalDate = pv.TimeStamp.LocalDate                   'subseconds
                                                sOutPut = ts.OutputString                               'sOutPut = 8/10/2010 7:35:52.30011 AM
                                                                                                        'should have moved to 8/10/2010 7:35:52.19011 AM

                                                PI Data


                                                Value                Event Time

                                                 

                                                416.1172           8/10/2010 7:34:19.57011 AM

                                                 

                                                392.1856           8/10/2010 7:35:52.19011 AM

                                                 

                                                Non-Update       8/10/2010 7:35:52.30011 AM

                                                 

                                                389.7436           8/10/2010 7:36:31.0601 AM

                                                 

                                                 

                                                  • Re: PI Event Time
                                                    cescamilla

                                                    Could you try passing a PITimeFormat object instead of passing a string? you are using a string that is not in the PI System format for Date Strings, that may be the issue. Using the PITimeFormat object will reduce the risk of having different date string types.

                                                      • Re: PI Event Time
                                                        aladams
                                                        I thought I was passing the PITimeFormat thru sOutPut?
                                                        PITimeServer.PITimeFormat ts = new PITimeServer.PITimeFormat 
                                                        ts.LocalDate = pv.TimeStamp.LocalDate
                                                        ts.FormatString = "M/dd/yyyy h:mm:ss.0000"
                                                        Dim sOutPut as String
                                                          • Re: PI Event Time
                                                            cescamilla

                                                            This is what I see:


                                                            Dim sOutPut as String

                                                            sOutPut = ts.OutputString  
                                                            Set pv = pt.Data.ArcValue(sOutPut, rtBefore)


                                                            So you are passing a String instead of a PITimeformat as a parmeter to ArcValue. you can actually use 'ts' in the next function.


                                                            Set pv = pt.Data.ArcValue(dtRequested, rtAtorBefore)
                                                            ts.LocalDate = pv.TimeStamp.LocalDate
                                                            'sOutPut = ts.OutputString

                                                            Set pv = pt.Data.ArcValue(ts, rtBefore)
                                                            ts.LocalDate = pv.TimeStamp.LocalDate
                                                            sOutPut = ts.OutputString    
                                                             
                                                            Set pv = pt.Data.ArcValue(ts, rtBefore)
                                                            ts.LocalDate = pv.TimeStamp.LocalDate
                                                            sOutPut = ts.OutputString

                                                              • Re: PI Event Time
                                                                aladams

                                                                So far using ts as the first argument seems to work.  I was trying to use ts.output instead of just the whole object ts.  Thanks again for your help.  I'll post if I run into any other problems with it.  I have about 3 to 4 weeks of work left on it.

                                                                 

                                                                THANKS FOR ALL THE HELP!

                                                          • Re: PI Event Time
                                                            andreas

                                                            Lynn,

                                                             

                                                            I guess you are still using the line ts.FormatString = "M/d/yyyy h:mm:ss.00000 AP" in your code?

                                                             

                                                            For me this seems to be the culprit - if you change it to ts.FormatString = "M/d/yyyy h:mm:ss.0000 AP" it works on my system. Could you reproduce this behavior?

                                        • Re: PI Event Time

                                          The PIValue object contains a PITime with the exact timestamp.  PITime only allows return of double seconds, VT_DATE (also a double), and FILETIME (masked as CURRENCY because COM doesn't know FILETIME).  The answer to your question is to use the PITimeFormat.OutputString method.

                                           

                                          "OutputString is a Read-Only property that returns a string representation of the internal time as a wall clock time. The format of the string is taken from the FormatString property if set, else it uses the Microsoft short date/time format but includes fractional seconds."

                                           

                                          Your solution becomes:

                                           
                                          Dim tmfmt as new PITimeFormat
                                          ...
                                          For Each pt In ptlist
                                            Set pv = pt.Data.ArcValue(x, y)
                                            tmfmt.UTCSeconds = pv.TimeStamp.UTCSeconds
                                            MsgBox cstr(pv.Value) & ", " & tmfmt.OutputString
                                          ...
                                          Next