3 Replies Latest reply on May 10, 2017 2:02 PM by Rick Davin

    How do you get the PI server's time from PI-SDK?

    jdouglas

      I'm just trying to do some calculations with PISDK.IPICalculation. I noticed that the timestamp from the return data is the client's time. I want the PI server's time from midnight to midnight, not the PC's.

       

      Dim m_LocalServer As PISDK.Server

      Dim strPE AS string = "If 'sinusoid' > 90 then 1 else 0"

      Dim z As PISDK.PIValues = calculation.Calculate(m_LocalServer.ServerTime, m_LocalServer.ServerTime, strPE, stRecordedValues, "")

       

      I tried using m_LocalServer.ServerTime. But it comes back with the client's time.

        • Re: How do you get the PI server's time from PI-SDK?
          Rick Davin

          I gather you are using VB.NET and not VBA.  Is this all the pertinent code?  I notice you never initialized m_LocalServer.

           

          Dim sdk As New PISDK.PISDK()

          Dim m_LocalServer As PISDK.Server = sdk.Servers.DefaultServer

          • Re: How do you get the PI server's time from PI-SDK?
            Rick Davin

            Hello again James,

             

            Let's talk about what's going on here.  The help for PISDK.Server.ServerTime states:

            Returns a PITime object representing the current time on the server to which the Server object is connected.

             

            Or as I would rather emphasize:

            Returns a PITime object representing the current time on the server to which the Server object is connected.

             

            So it represents the current time AS a PITime.  And by current time it means current instance in time, or what the server host thinks would be UtcNow.  This makes the  PISDK.Server.ServerTime a poor fit for what you want because it really lacks time zone context.  ServerTime is more for finding clock drift between 2 servers or an interface and a server.

             

            CORRECTION:

            What you are more interested in would be the Server.PITimeZoneInfo property.  And you'd want to read more about PITimeServer.PITimeZoneInfo object.

             

             

            Note also the AFSDK PIServer class has a ServerTimeZone property along with its ServerTime property could be used to achieve what you ask.  It does it a bit more cleaner, and of course, without using a technology transitioning for deprecation.

            2 of 2 people found this helpful
            • Re: How do you get the PI server's time from PI-SDK?
              Rick Davin

              Okay James here we go ...

               

              The trick is to get the time zone info from your data archive.  You would then pass a time string along with a time zone to fetch the UTC instant in time (UTCSeconds most helpful here).  With those UTCSeconds, you set a PITime - but remember a PITime lacks time zone info and is a UTC-based instant in time with the ability to show you the data locally to the client app (not the remote data archive).

               

              I created a PTimeExtensions class for some handy extension methods:

               

              public static class PITimeExtensions
              {
                  public static PITime ConvertToPITime(this PISDK.Server dataArchive, string inputString)
                  {
                      return ConvertToPITime(dataArchive?.PITimeZoneInfo, inputString);
                  }
                  public static PITime ConvertToPITime(this PITimeZoneInfo timezone, string inputString)
                  {
                      var fmt = new PITimeFormat();
                      fmt.TimeZoneInfo = timezone;
                      fmt.InputString = inputString;
                      var time = new PITime();
                      time.UTCSeconds = fmt.UTCSeconds;
                      return time;
                  }
              }
              

               

              Here's an example of usage:

               

              var houston = ClientSDK.Servers["local_server"];
              var philly = ClientSDK.Servers["philly_server"];
              var oakland = ClientSDK.Servers["oakland_server"];
              
              houston.Open();
              philly.Open();
              oakland.Open();
              
              var central = houston.PITimeZoneInfo;
              var eastern = philly.PITimeZoneInfo;
              var pacific = oakland.PITimeZoneInfo;
              
              Console.WriteLine($"My location is Houston with a time zone of {central.StandardName}");
              Console.WriteLine($"Yesterday midnight for {central.StandardName} would be {houston.ConvertToPITime("y").LocalDate} {central.StandardName}");
              Console.WriteLine($"Yesterday midnight for {eastern.StandardName} would be {philly.ConvertToPITime("y").LocalDate} {central.StandardName}");
              Console.WriteLine($"Yesterday midnight for {pacific.StandardName} would be {oakland.ConvertToPITime("y").LocalDate} {central.StandardName}");
              

               

              And here is the resulting output:

               

              My location is Houston with a time zone of Central Standard Time

              Yesterday midnight for Central Standard Time would be 5/9/2017 12:00:00 AM Central Standard Time

              Yesterday midnight for Eastern Standard Time would be 5/8/2017 11:00:00 PM Central Standard Time

              Yesterday midnight for Pacific Standard Time would be 5/9/2017 2:00:00 AM Central Standard Time

               

              That should point you in the right direction!

               

              UPDATE Conversion to VB.NET:

               

              Imports System.Runtime.CompilerServices
              Imports PITimeServer
              Module PITimeExtensions
              
                  <Extension()> Public Function ConvertToPITime(dataArchive As PISDK.Server, inputString As String) As PITime
                      Return ConvertToPITime(dataArchive.PITimeZoneInfo, inputString)
                  End Function
              
                  <Extension()> Public Function ConvertToPITime(timezone As PITimeZoneInfo, inputString As String) As PITime
                      Dim fmt As New PITimeFormat()
                      fmt.TimeZoneInfo = timezone
                      fmt.InputString = inputString
                      Dim time As New PITime()
                      time.UTCSeconds = fmt.UTCSeconds
                      Return time
                  End Function
              
              End Module
              
              1 of 1 people found this helpful