7 Replies Latest reply on Apr 27, 2018 8:04 AM by KenjiHashimoto

    How to export digital tags with PowerShell?

    Innes247

      Hello

       

      I'm looking for some advice on how to export digital tags in PowerShell in minute intervals between a start and end time? I’m able to do this with analogue tags using the 'Get-PIExpressionSummary ' but I can’t find a function that works for digital tags?

      Background: I’m trying to do a daily export of multiple digital tags to an csv file.

       

        • Re: How to export digital tags with PowerShell?
          afink

          Hello,

           

          It sounds like what you are looking for is getting interpolated values for a given tag.  Unfortunately, this functionality has not yet been built into the PowerShell Tools for the PI System.  See WI197586.

           

          To work around this, you could use a loop to grab interpolated values for the digital tags at a given interval.  For example, the example below gets values for the last week on a daily interval at midnight.

          # Create an empty array
          $PIValues = @()
          
          
          # Define start and end time for time range
          $StartTime = ConvertFrom-AFRelativeTime T-7d
          $EndTime = ConvertFrom-AFRelativeTime T
          
          
          # Loop to get 1 value for each day
          for ($CurrentTime = $StartTime; $CurrentTime -le $EndTime; $CurrentTime = $CurrentTime.AddDays(1))
          {
              # Get value and add the PIValues array
              $PIValues += Get-PIValue -PointName DigitalTag -Time ($CurrentTime) -ArchiveMode Interpolated -Connection $con
          }
          

           

          Another thing to note, is that the values returned for digital tags contain the Digital State and Digital State Set integers.  So if you further want your export to include the string representations of these values, you will need to further use the Get-PIDigitalStateSet cmdlet and then use the values returned to get the correct string representation before exporting to your .csv file.

           

          Hope this helps,

          Adam

          2 of 2 people found this helpful
            • Re: How to export digital tags with PowerShell?
              gregor

              I believe there is some confusion as it doesn't make much sense to me to interpolate a discrete signal. Getting the state value at a given time however makes sense to me.

               

              The hint to Get-PIDigitalSet is correct but I believe what Paul was looking for is how you get the Digital States string representation.

              I was looking into answering Paul's  question too and I am honestly still "confused" about how OSIsoft.PowerShell module represents the values for digital tags:

               

              Value          : State: 4(Set: 3)

               

              What?! .. Why?

               

              # Make connection to the default PI Data Archive
              $DefaultConf = Get-PIDataArchiveConnectionConfiguration -Default
              $connection = Connect-PIDataArchive -PIDataArchiveConnectionConfiguration $DefaultConf
              
              # Define PI Point name
              $piPointName = "CDM158"
              
              # Retrieve list of events for the defined PI Point
              $piVals = Get-PIValue -PointName $piPointName -Connection $connection -StartTime "10-Apr-2018 6:00:00 AM" -EndTime "10-Apr-2018 12:00:00 PM" -MaxCount 1000
              
              # Define output file and path 
              $PathFileName = "C:\Temp\CSV\" + $piPointName + ".csv"
              
              # Inform the user
              Write-Host $piVals.Count " values will be written to " $PathFileName
              
              # Create an object to store the results
              $csvValues = @()
              
              # Create and add a header
              $csvHeader = "PIPoint,IsGood,Timestamp,Value"
              $csvValues += $csvHeader
              
              # Create empty string to store the results
              $csvVal = ""
              
              # Loop through the values and add what we need to the string
              foreach ($piVal in $piVals)
              {
                  $csvVal += $piPointName.ToString() + ","
                  $csvVal += $piVal.IsGood.ToString()  + ","
                  $csvVal += $piVal.Timestamp.ToString() + ","
              
                  # Instead of the string representation of the Digital State, the Value
                  # property has StateNo and StateSetNo.
                  # This is confusing!!! and requires additional work :-(
                  $digStateSet = Get-PIDigitalStateSet -Connection $connection -id $piVal.Value.StateSet
                  $stateVal = $digitalStateSet[$piVal.Value.State]
                  $csvVal += $stateVal.ToString() + "`n"
              }
              $csvValues += $csvVal
              
              # Write Csv file
              Out-File -FilePath $PathFileName -InputObject $csvValues
              

               

              Edit: Removed some nasty dust from the code snippet and applied a nicer format

              3 of 3 people found this helpful
                • Re: How to export digital tags with PowerShell?
                  afink

                  I agree there was some confusion, and I apologize if my earlier response was cryptic.  I think there are two issues here:

                  1. Retrieve values on a given interval

                  2. How to handle digital values returned via the PowerShell tools

                   

                  Since the tag would be configured as digital, the retrieval mode of interpolated will still return the correct value and will not return an incorrect decimal digital state value, such as 2.5.  I should have been more clear on this in my example.

                   

                  The PowerShell tools return the digital values in the same manner as they are archived within the PI Data Archive, as integral digital state/digital state set offsets.  This is done on the PI Data Archive for more efficient archiving of the data.  This can also prove advantageous for large calls since you can simply send the integral representations rather than full string values and cause less load on networks, etc.  The disadvantage is obviously that the client then needs to provide it's own logic for converting these values and displaying the proper string representation of the state.  Thanks for providing some additional example code for how to go about doing this using Get-PIDigitalStateSet in your response

                   

                  Hopefully this clears up the confusion regarding the digital state values returned by the PowerShell tools.

                   

                  - Adam

                    • Re: How to export digital tags with PowerShell?
                      gregor

                      Hi Adam,

                       

                      Yes, your response clears up some confusion. Thank you! But it also makes me believe you received my post as a personal offense. Please accept my apologies and also be assured that it wasn't meant this way.

                       

                      I am familiar with the Digital State concept but I cannot remember I ever saw it implemented like this. Usually, a native PowerShell script would be shorter and less complex compared to one which is based on another library like AF SDK. Even the results of the following script cannot really be compared to what the script does which I posted earlier, I like to share my AF SDK based script too as it comes way more natural and you will recognize that it works with PI Points of any type. With OSIsoft.PowerShell Digital points have to be treated different than points of other type. The AF SDK based script doesn't require a special treatment of the AFValue objects Value property because the Value property always contains the value representation.  

                      While we are talking, I also believe that OSIsoft.PowerShell is lacking some important data retrieval methods. Yes, I may create a Uservoice request to enhance OSIsoft.PowerShell but personally find it more natural to build my PowerShell scripts based on AF SDK. This is because I am more familiar with AF SDK than any other Developer Technology.

                       

                      # Load the AF SDK assembly through reflection
                      [Reflection.Assembly]::LoadWithPartialName("OSIsoft.AFSDK") | Out-Null
                      
                      # Connect to the default PI Data Archive
                      [OSIsoft.AF.PI.PIServers] $piSrvs = New-Object OSIsoft.AF.PI.PIServers
                      [OSIsoft.AF.PI.PIServer] $piSrv = $piSrvs.DefaultPIServer
                      
                      # Define array of PI Point Names
                      $piPointNames = @()
                      $piPointNames = $piPointNames + "SINUSOID"
                      $piPointNames = $piPointNames + "CDT158"
                      $piPointNames = $piPointNames + "CDM158"
                      
                      # Define the time range for data retrieval
                      [OSIsoft.AF.Time.AFTimeRange] $timeRange = New-Object OSIsoft.AF.Time.AFTimeRange("*-4h", "*")
                      
                      # Create one XML file for each PI Point
                      foreach ($piPointName in $piPointNames)
                      {
                          # Load PI Point
                          [OSIsoft.AF.PI.PIPoint] $piPoint = [OSIsoft.AF.PI.PIPoint]::FindPIPoint($piSrv, $piPointName)
                      
                          # Retrieve values
                          [OSIsoft.AF.Asset.AFValues] $piValues = $piPoint.RecordedValues($timeRange, [OSIsoft.AF.Data.AFBoundaryType]::Inside, $null, $true, 1000)
                      
                          # Define output file path and name
                          $OutputFile = "C:\Temp\CSV\" + $piPointName + ".csv"
                      
                          # Inform the user
                          Write-Host $piValues.Count " values will be written to " $OutputFile
                      
                          $CsvValues = @()
                          # Convert $piValues to CSV
                          foreach ($piVal in $piValues)
                          {
                              $CsvVal = ConvertTo-Csv -InputObject $piVal
                              $CsvValues += $CsvVal
                          }
                      
                          # Save the $CsvValues object to file
                          Out-File -FilePath $OutputFile -InputObject $CsvValues
                      }
                      
                        • Re: How to export digital tags with PowerShell?
                          afink

                          Gregor,

                          No problem at all I certainly took no offense.  Quite the contrary I re-read my original response after seeing your additions and was not satisfied with the clarity of my post. 

                           

                          I agree one of the trickiest parts of working with the PowerShell tools is that digital values need to be handled separately from other data types.  This can be especially confusing when SYSTEM digital state values are included within query results containing "good" values.  The fact that AFSDK is able to handle all events the same is definitely advantageous, and especially so in scenarios such as this one.

                           

                          - Adam

                  • Re: How to export digital tags with PowerShell?
                    Innes247

                    Thanks for your help guys,

                    I've gone with Kenji Hashimoto examples in the below link using the AFSDK Interpolated Values example, it does the job for me and it returns the actual digital value (Yes/No) as well. 

                     

                    Powershell and AFSDK example