10 Replies Latest reply on Feb 22, 2018 7:43 PM by knightk

    Converting Wind Direction to Text

    pegentry

      So we are pulling in some weather data from a field location and it is coming in as a number, (210). What is the best way to  convert that to text values? SSW, S, SSE, etc.

      trying to just do an if statement, but not working..

       

      Thanks

        • Re: Converting Wind Direction to Text
          vkaufmann

          Hi Perry,

           

          I think your best two options are to create either an enumeration set that maps your numbers to a cardinal direction if you are consuming the data using AF or if you are consuming the data directly from the Data Archive you can create a Digital State set which is the Data Archive analog.

           

          https://livelibrary.osisoft.com/LiveLibrary/content/en/server-v7/GUID-AD196D07-431C-4A28-9DD0-579CC93A6553

           

          https://livelibrary.osisoft.com/LiveLibrary/content/en/server-v7/GUID-9777EA12-0A0C-47E4-8A43-F0CF673E1DD0

           

          --Vince

          • Re: Converting Wind Direction to Text
            Rick Davin

            Hi Perry,

             

            Can you tell us more about what you are doing?  You say you are trying an if statement but what is that in?  PI PE?  AF Formula?  PI SDK code?  AF SDK code?  Are you creating your own interface and trying to write the Wind Direction "text" to a Data Archive?  Note I have text in quotes because I think Vince is correct in that you probably want a Digital State set.  You will need to decide how many states you desire in the state set.

             

            This would probably be too coarse:

            N, E, S, W

             

            This is better but probably not sufficient:

            N, NE, E, SE, S, SW, W, NW

             

            Or you probably want this 16 point compass:

            N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW

             

            Then whatever code technology you are using for your if statement, you will need to make the judgement on what raw integer value falls into which wind direction state.  You also have to consider border cases, i.e. decide upon "less than" versus "less than or equal to".  For example, what to do if the raw integer falls exactly between NNE and NE?  I personally would favor rounding to the shorter text, that is to say I'd choose NE in a tie-breaker with NNE because NE is shorter to read.  But that's me.  Or to complicate it more, if you are making an interface and the previous state would have been NNE, then let it be favored in a tie?

             

            So the state set would  have 16 states, each of which covers 22.5 degrees in a 360 degree circle.  That would mean +/- 11.25 degrees on either side of a state's middle azimuth.  For instance, East or E has a middle azimuth of 90 degrees so its range would be 78.75 - 101.25.  But ENE ranges from 56.25 - 78.75.  So you need to decide in your own logic what direction 78.75 really is.

             

            Wind Direction and Degrees

             

            And this Wikipedia link shows 32 compass points.  While this may be too much for you, it's interesting to note in the table that they don't have overlapping points.  East ranges from 84.38 to 95.62, and the next point of East by south starts at 95.63.

             

            All that said, here's one possible implementation using AF SDK:

             

            Using PI-SMT, define a stateset named "Compass16pt".

             

            2016-09-26 06_29_48-Digital States - PI System Management Tools.png

             

            Your code should make a reference to the PIServer of interest and then grab the state set.

             

            // Set the Data Archive and compass states
            PIServer dataArchive = PIServers.GetPIServers().DefaultPIServer;
            AFEnumerationSet compassStates = dataArchive.StateSets["Compass16pt"];
            

             

            You say the wind direction is coming to you as a number.  Is that an Int32, Float, or Double?  Shouldn't matter in my example AF SDK code below as all will be cast to double.

             

            AFEnumerationValue GetCompassDirection(AFEnumerationSet compassStates, double rawDegrees)
            {
                 // adjusted will be >= 0 but strictly < 360 
                double adjusted = (rawDegrees + 11.25) % 360;
                int index = (int)Math.Truncate(adjusted / 22.5);
                return compassStates[index];
            }
            
            
            

             

            Tie-breaking goes to the higher index.  For example, if your rawDegrees was 11.25, which favors NNE over N.  Why?  The rawDegrees gets adjusted to 22.5.  When divided by 22.5 and truncated, the index is 1. 

             

            Rick

            1 of 1 people found this helpful
            • Re: Converting Wind Direction to Text
              pegentry

              Follow up to this. Found out there were many ways. AF  Structure below with Analyses Expression below is what we ended up with.

               

              belcap.JPG

               

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 11.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 33.75 then String('Belridge Wind Direction|NNE')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 33.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 56.25 then String('Belridge Wind Direction|NE')

              else 

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 56.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 78.75 then String('Belridge Wind Direction|ENE')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 78.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 101.25 then String('Belridge Wind Direction|E')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 101.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 123.75 then String('Belridge Wind Direction|ESE')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 123.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 146.25 then String('Belridge Wind Direction|SE')

              else

              if 'Belridge Wind Direction Degree' >= 146.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 168.75 then String('Belridge Wind Direction|SSE')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 168.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 191.25 then String('Belridge Wind Direction|S')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 191.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 213.75 then String('Belridge Wind Direction|SSW')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 213.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 236.25 then String('Belridge Wind Direction|SW')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 236.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 258.75 then String('Belridge Wind Direction|WSW')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 258.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 281.25 then String('Belridge Wind Direction|W')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 281.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 303.75 then String('Belridge Wind Direction|WNW')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 303.75 and 'Belridge Wind Direction|Belridge Wind Direction' < 326.25 then String('Belridge Wind Direction|NW')

              else

              if 'Belridge Wind Direction|Belridge Wind Direction' >= 326.25 and 'Belridge Wind Direction|Belridge Wind Direction' < 348.75 then String('Belridge Wind Direction|NNW')

              Else

              String('Belridge Wind Direction|N')