4 Replies Latest reply on Feb 15, 2018 4:42 PM by @LCL

    Is there a Use Server Timezone option in PI-AF like in PI SMT or datalink?

    @LCL

      Hello,

      I would like to know the local time of a distant PI server. That's why I created a PE tag to store that data continuously on this distant server.

      Here what I did:

      On a chinese pi server, I created this:

      Now, I can visualize the time delta between me and the chinese server if I use the server timezone option:

       

      Now, I would like to retrieve this information in the PI-AF:

      But I don't know how to find the "use server timezone" option in PI-AF.

       

      Does somebody know how to?

       

      Thanks,

      Louis.

        • Re: Is there a Use Server Timezone option in PI-AF like in PI SMT or datalink?
          Rick Davin

          Hi Louis,

           

          Since your question is about PI AF SDK, I have moved your post the the PI .NET Framework subspace.

          • Re: Is there a Use Server Timezone option in PI-AF like in PI SMT or datalink?
            vkaufmann

            There is not a notion of server timezones in the AF SDK. As a direct reply to your question, I don't believe this functionality was implemented in PI System Explorer.

             

            Timestamp interpretation is always handled by the PI Data Archive and not the AF SDK directly. The server takes the request made in the AF SDK and returns events in UTC back. It is then up to the client to determine how those results are displayed. The DateTime objects that are consumed by the data methods in the AF SDK are understood as their UTC equivalents. You can see this with the following code. The time3 object is specifically set with a UTC DateTimeKind so this object is built specifically as a UTC DateTime. Display time is always up to the client. The Data Archive internally only deals with UTC timestamps. The below code highlights this.

             

                        AFTime time1 = AFTime.Parse("11/30/2017 08:00:00 AM");

                        AFTime time2 = time1.UtcTime;

                        DateTime time3 = new DateTime(2017, 11, 30, 8, 0, 0, 0, DateTimeKind.Utc);

             

                        var val1 = myAtt.GetValue(time1);

                        var val2 = myAtt.GetValue(time2);

                        var val3 = myAtt.GetValue(time3);

                        Console.WriteLine($"Value at {time1:o} is {val1}");

                        Console.WriteLine($"Value at {time2:o} is {val2}");

                        Console.WriteLine($"Value at {time3:o} is {val3}");

             

             

            As a matter of fact, .NET framework does not have a method for specifying the timezone of your DateTime objects either. So you will have to manage this in code yourself.

             

            https://stackoverflow.com/questions/1120325/setting-changing-an-net-applications-timezone

             

            This code implements a method to adjust your input by the offset between 2 timezones and the make a request at the offset time. Which should do something similar to what you are looking for.

             

                        TimeZoneInfo serverTZ = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");

                        AFTime adjustedEnd = ParseDateTimeAsTimeZone("*", serverTZ);

                        AFTime adjustedStart = ParseDateTimeAsTimeZone("*-1h", serverTZ);

                        AFTimeRange range = new AFTimeRange(adjustedStart, adjustedEnd);

                        AFTimeSpan span = new AFTimeSpan(minutes: 1);

                        var data = myAtt.Data.InterpolatedValues(range, span, null, null, false);

             

                        foreach (var val in data)

                        {

                            Console.WriteLine($"{val.Timestamp} {val.Value}");

                        }

                        Console.WriteLine(new String('=', 60));          

                        Console.ReadLine();

                    }

             

                    private static DateTime ParseDateTimeAsTimeZone(string time, TimeZoneInfo tzinfo)

                    {

                        DateTime localTime = new DateTime(AFTime.Parse(time).LocalTime.Ticks, DateTimeKind.Local);

                        TimeSpan offset = tzinfo.BaseUtcOffset - TimeZoneInfo.Local.BaseUtcOffset;

                        return localTime + offset;

                    }

            3 of 3 people found this helpful
            • Re: Is there a Use Server Timezone option in PI-AF like in PI SMT or datalink?
              Rick Davin

              Hello again Louis,

               

              PITime and AFTime both use UTC as the payload to the underlying time.  It's then left up to whatever client application to display the time in a given time zone.  Being that you are working with .NET, you would then use the TimeZoneInfo class or the DateTimeOffset structure according to your needs.  You may also consider the third party library of NodaTime.

               

              PI SDK does not have a feature called "Use server timezone".  Rather the WinForm application called "PI-SMT" offers that.  This is fairly simple to achieve given the one PI point shown is connected to exactly one data archive.  Data Link is also a separate UI-based add-in.

               

              The WinForm application we call "PI System Explorer" is not meant to be a end-user asset viewer.  Rather, we consider it to be a configuration tool.  It's left up to you to create a custom application and display the time zone as you see fit.  Note too that a given AFDatabase may reference more than 1 data archive.

               

              An example application that displays times in different time zones may be found on GitHub for the AFDataViewer.

               

              If you insist on showing the timestamp in PSE that is not UTC or the client's local time, then a data reference could be written.  An input to the data reference would either be a given PIPoint or else a TimeZoneInfo time zone name.  If you pass in a PIPoint, you would need to have your data reference connect to the data archive to fetch it's PIServer.ServerTimeZone property.  If you want to convert a history of values, you would have to retrieve data and convert the timestamps to the ServerTimeZone.  If you only cared about showing the current time of the PIServer, then you just use the PIServer.ServerTime property.

               

              Good luck.

              1 of 1 people found this helpful
              • Re: Is there a Use Server Timezone option in PI-AF like in PI SMT or datalink?
                @LCL

                Thanks for your answers,

                These are very detailed and documented.

                At first, I was wondering: "SMT and datalink can do that, so why PSE won't be able to?" but I understand now why it's not so evident.

                Anyway, in order to workaround this problem, I'll reconfigure my PE tag PIServerTime as a string type. By the way, the chinese server will always send me the server local time.

                No jokes anymore!