Reading PI-DB with Win32::OLE and PISDK

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!


I'm trying to read data from PI-db from company Osisoft using OLE and the PI-SDK (win 7 with strawberry perl V5.18.2, PISDK version 1.4.0 build 416).
I can read the snapshotdata of a PI-tag, but calling method "RecordedValues" I allways get an error message
"win32::OLE(0.1711) error 0x80020005: "Typkonflikt"
     in METHOD/PROPERTYGET "RecordedValues" argument "BoundaryType" at line ..
An internet search shows ( (translated from german):
The error message occurs only if the following conditions are met:
- the parameter is passed by reference
- the corresponding Visual Basic data type is either Byte, Integer, Single or Double
This behaviour is intended.

Perhaps the error is that Perl passes parameter by referenz, but the argument "BoundaryType" has to be passed by value.
The PI-Help-Utility looks like this:
RecordedValues Method (PIData object)

This method returns compressed values for the requested time range from the archive as a PIValues collection.
object.RecordedValues StartTime, EndTime, BoundaryType, [FilterExp], [ShowFiltered], [AsyncStatus]

The RecordedValues method syntax has these parts:
Part Description  
object         An object expression that evaluates to a PIData object.  
StartTime      A Variant containing the time. See the Settings section for allowable values.
EndTime        A Variant containing the time. See the Settings section for allowable values. When ...
BoundaryType   A value from the BoundaryTypeConstants enumeration type that determines how the times and values of the returned end points are determined.  

You get the BoundaryTypeConstants with (my $piConst = Win32::OLE::Const->Load($PI);),
possible values are 0,1,2,3 and should be declared as .NET-Enumeration of type int (4 Bytes).
I've tried various ways to call the method, but the error message remains.
Here is an extract of the perl code:

#! /usr/bin/perl
use warnings;
use strict;
use Win32::OLE;
use Win32::OLE::Const;
use Win32::OLE::Variant;

my $PI = Win32::OLE->new('PISDK.PISDK') or die "PISDK Error: ",Win32::OLE->LastError();
my $piConst = Win32::OLE::Const->Load($PI);
#print "PiConst: $_ \t= $piConst->\n"
    for (sort(keys(%$piConst)));   # print all constants

my $server = $PI->Servers->Item("Servername") or
    die "No PI server Objekt: ",Win32::OLE->LastError(),"\n";
my $status = $server->Open("UID=Username;PWD=Userpassword");

print_point ('PI-Tag_Name');

sub print_point {
    my $piTag = $_[0];
    my $point = $server->PIPoints->item($piTag);
    print "\npiTag: $piTag  Point: $point\n";
    unless ($point) {
       print "piTag $piTag kann nicht gelesen werden\n";
    print "\t$_ = $point->\n" for (sort(keys(%$point)));   # ok
    print "\tData: $_ = $point->Data->\n"
          for (sort(keys(%})));   # ok
    print "\tData-Snapshot: $_ = $point->Data->Snapshot->\n"
          for (sort(keys(%})));   # ok
    my $startTime = Variant(VT_DATE,'05.01.2015 12:00:00');
    my $endTime   = Variant(VT_DATE,'07.01.2015 23:45:00');
    my $btFlag = Variant(VT_I4,$piConst->);
    $Win32::OLE::Warn = 3;
    my $recValues = $point->Data->RecordedValues
       ($startTime,$endTime,$btFlag);                    # error "Typkonflikt" at argument "BoundaryType"
    my $recValues = $point->Data->RecordedValues
       ($startTime,$endTime,$piConst->);       # same error
    my $recValues = $point->Data->RecordedValues
       ('05.01.2015 12:00:00','07.01.2015 12:00:00',0);  # same error
    my $recValues = $point->Data->RecordedValues
       ( {StartTime => "05.01.2015 12:00:00",            # same error
          EndTime => "07.01.2015 12:00:00",
          BoundaryType => Variant(VT_I4,0)} );   # BoundaryType => 0}

Site Timeline