6 Replies Latest reply on Apr 18, 2016 3:18 PM by gregor

    Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.

    imuehlenhoff

      Hi there, I'm new with PowerShell: I'm trying to figure out how to use PI-SDK objects and methods in PowerShell.
      Therefore I wrote a little ps-script to get some snapshots and archive values from PI-SDK.
      I have no problem to get values from sinusoid's Snapshot property.
      But I don't know, how to call the SDK-Methods RecordedValues() or ArcValue() correctly.
      I tested several different combinations of arguments. Most attempts leaded to "Type mismatch" errors.  

      Here is the script and its output: Has anybody an idea?:

       

      [reflection.assembly]::loadwithpartialname("OSIsoft.PISDK") | out-null
      $pisdk = new-object PISDK.PISDKClass;
       
      $myTagName = 'Sinusoid'
      write-host "Snapshot-Value for Tag:" $myTagName
      $srv = $pisdk.Servers.DefaultServer
      write-host -foregroundcolor Blue "My default PI-Server: " $srv.Name
      $myPIPoint = $srv.PIPoints.Item($myTagName)
      $myPIValue1 = $myPIPoint.Data.Snapshot
      write-host -foregroundcolor Green $myTagName '-Snapshot:' $myPIValue1.Value','$myPIValue1.TimeStamp.LocalDate

      write-host 'Archive-values for'$myTagName ':'
      $btType = [PISDK.BoundaryTypeConstants]::btInside
      write-host "My BoundaryTypeConstant =" $btType  ## Test this enumeration-type...
      $rtType = [PISDK.RetrievalTypeConstants]::rtAtOrBefore
      write-host "My RetrievalTypeConstant =" $rtType ## Test this enumeration-type...
      $et = get-date   ## get Endtime "now()"
      $st = $et.date   ## get Starttime "end()"
      write-host 'My Timerange:' $st ';' $et

      ## So far so good: Up to this point my little script works as expected.


      $myPIValue2 = $myPIPoint.Data.ArcValue('*',[PISDK.RetrievalTypeConstants]::rtAtOrBefore)

       

      ##$myPIValue2 = $myPIPoint.Data.ArcValue("*",[PISDK.RetrievalTypeConstants]::rtAtOrBefore,[void]$Null)
      ##$myPIValue2 = $myPIPoint.Data.ArcValue($et,[PISDK.RetrievalTypeConstants]::rtAtOrBefore,[void]$Null)

      ##Write Archive-Value:
      ##write-host -foregroundcolor Green $myTagName ':' $myPIValue2.Value','$myPIValue2.TimeStamp.LocalDate

       

      $myPIValues = $myPIPoint.Data.RecordedValues('T','*',0,'1')

       

      ##$myPIValues = $myPIPoint.Data.RecordedValues('01.02.2012','02.02.2012',0,'1',1,0)
      ##$myPIValues = $myPIPoint.Data.RecordedValues($st,$et,[OSIsoft.PISDK.BoundaryTypeConstants]::btInside,"1",True,False)
      ##$myPIValues = $myPIPoint.Data.RecordedValues($st,$et,[PISDK.BoundaryTypeConstants]::btInside,"1",1,0)

      ##Write Archive-Valus:
      ##foreach( $myPIValue3 in $myPIValues ){
      ## write-host -foregroundcolor Green $myTagName ':' $myPIValue3.Value',' $myPIValue3.TimeStamp.LocalDate
      ##}


      ==> Script-output:
      Snapshot-Value for Tag: Sinusoid
      My default PI-Server:  PICollective
      Sinusoid -Snapshot: 1,820472 , 10.02.2012 08:28:59
      Archive-values for Sinusoid :
      My BoundaryTypeConstant = btInside
      My RetrievalTypeConstant = rtAtOrBefore
      My Timerange: 10.02.2012 00:00:00 ; 10.02.2012 08:33:44

      Exception calling "ArcValue" with "2" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020
      005 (DISP_E_TYPEMISMATCH))"
      At C:\Documents and Settings\muehlenh\Desktop\PowerShellTestScript2.ps1:38 char:39
      + $myPIValue2 = $myPIPoint.Data.ArcValue <<<< ('*',[PISDK.RetrievalTypeConstants]::rtAtOrBefore)
          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
          + FullyQualifiedErrorId : ComMethodTargetInvocation

      Exception calling "RecordedValues" with "4" argument(s): "Type mismatch. (Exception from HRESULT: 0
      x80020005 (DISP_E_TYPEMISMATCH))"
      At C:\Documents and Settings\muehlenh\Desktop\PowerShellTestScript2.ps1:45 char:45
      + $myPIValues = $myPIPoint.Data.RecordedValues <<<< ('T','*',0,'1')
          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
          + FullyQualifiedErrorId : ComMethodTargetInvocation

          • Re: Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.
            imuehlenhoff

            Yes I did. I started with "Scripting MDB edits". But I did'nt found an answer to my question regarding "RecordedValues" and "ArcValue".

              • Re: Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.
                mhamel

                Hi Ingo,

                 

                PowerShell requires all parameters of a given method as the C# language does (This is true for .NET Framework 2.0, 3.0, 3.5 but not for version 4.0). Per the PI SDK documentation, the ArcValue method requires 3 arguments: Timestamp, Mode and AsynchStatus. When you are passing less than the required arguments, PowerShell will complain about a Type Mismatch error.

                 

                You can fix your problem by instantiating an empty AsynchStatus object like this:

                 
                $_Asynch = New-Object PISDKCommon.PIAsynchStatusClass
                

                 but you would need to reference the PISDKCommon assembly by reflection. I have added an example of custom cmdlet that takes 4 arguments to perform a RecordValue against a specific tag. In addition, you will see there is a section on how to handle the value if it is a digital state instead of an analog value. If you want the PowerShell script, you can click here.

                 

                14855-_2D00_-sc1.png

                 

                14855-_2D00_-sc2.png

                 

                Let me know if that answered your question.

                  • Re: Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.
                    imuehlenhoff

                    Hi Mathieu, thank you very much. Thats exactly what what I needed! :-)

                     

                    My call of ...

                     

                    $myPIValues = $myPIPoint.Data.RecordedValues('Y','T',[PISDK.BoundaryTypeConstants]::btInside,"1",0,$_Asynch)

                     

                    ... works also fine with this AsynchStatus object.

                     

                    Best regards

                     

                    Ingo

                    • Re: Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.
                      agalambos

                      Hello Mathieu,

                      A customer I was speaking with on the tech support line was interested in getting access to the script linked in this entry. I think the link was broken with the move to the new pisquare. Is it possible for you to send that to me or fix the link?

                      Thanks,

                      Addison Galambos

                        • Re: Using PI-SDK method 'RecordedValues' and/or 'ArcValue' in Powershell.
                          gregor

                          Please accept our apologies that the attachment has become lost. Honestly, I am not too sad because the Developer Technology used is PI SDK which is announced to become deprecated and hence not recommended with recent developments.

                           

                          It's maybe not as mature as Mathieu's script nor is it as comfortable and flexible but I like to offer below AF SDK based script as alternative. Perhaps the community likes to develops it to higher orders. If the script does not do what you are looking for or you like to have some additions, please feel encouraged to ask.

                           

                          # Loading AF SDK through Reflection
                          [System.Reflection.Assembly]::LoadWithPartialName("OSIsoft.AFSDK")
                          # Please change below to a) the name of your PI Data Archive host
                          $PIServerName = "PIServer"
                          # and b) the name of the PI Point you like to retrieve data for
                          $PIPointName = "CDT158"
                          $KnownServers = New-Object OSIsoft.AF.PI.PIServers
                          $Server = $KnownServers[$PIServerName]
                          $Server.Connect()
                          if ($Server.ConnectionInfo.IsConnected -eq $true)
                          {
                              # Loading the PI point
                              $PIPoint = [OSIsoft.AF.PI.PIPoint]::FindPIPoint($Server, "CDT158")
                              # Defining the time range (here '*-8h' to '*')
                              $EndTime = [OSIsoft.AF.Time.AFTime]::NowInWholeSeconds
                              $StartTime = $EndTime.LocalTime.AddHours(-8)
                              $timeRange = New-Object OSIsoft.AF.Time.AFTimeRange($StartTime, $EndTime)
                              # Query recorded values
                              $recordedValues = $PIPoint.RecordedValues($timeRange, [OSIsoft.AF.Data.AFBoundaryType]::Inside, "", $true, [System.Int32]::MaxValue)
                              # Return results at the prompt
                              $recordedValues
                          }