最近公司组织培训PI数据库,在听课之余试验了一下java直接读取PI数据库。
安装数据库。
安装osi ,启动PIPerfMon_Basic.bat,使用process book 绘制一个趋势图,加入几个例子测点,如“CDT158”,如图:
Piapi简介
利用PIAPI直接操作PI,安装PI数据库后会有一个piapi32.dll,提供了.net读取的接口。
Jnative简介
JNative是一种能够使Java语言使调用DLL的一种技术,对JNI进行了封装。我们将下载的jnative.jar解压后,有一个jNativeCpp.dll,将其拷入C:\windows\system32下,并将jnative.jar加载到我们项目中来。准备工作就绪。
程序读取。
要点记录: 阅读API。打开PI System->about PI SDK->View Help,即可看到api文档。 PI数据库的数据分别存储在Snapshot或者Archive中,一个是快照一个是档案文件,这样做是为了方便PI数据库对数据进行压缩.那么自然对数据库的读取也分为对Snapshot和Archive读取.snapshot和archive的值都是用PIValue的形式表示的, PIValue对象包括了数值和时间。 其中Pi的api中,用到最多的函数组是time functions、archive functions、snapshot functions。time functions包含很多对时间处理的函数; archive functions包含了对档案文件的读写的函数;snapshot functions包含了对快照的读取函数。 时间处理。 .net调用piapi传入时间类型时,是将.net的Date类型转为int数组,并可以直接将int数组传入方法。Java使用时间类型稍微复杂一些,需要调用pitm_intsec方法,该方法帮助如下: PIVOID pitm_intsec( int32 PIPTR * timedate, int32 timearray[6] );
Returns
None
Arguments
timedate (returned)
PI time stamp
timearray (passed) 表示该方法2个参数,第一个是一个int型数组(指针),第二个参数是一个int型数组。第一个参数是返回参数,第二个参数是传入参数。 注意,传入int32 timearray[6]参数时,必须使用Pointer模拟指针,并且,循环设置数组元素时,注意pointer.setIntAt(int offset, int value),offset的下标,比如第一个元素是0,第二个元素不是1,要看int占几个字节,int在。Net中占4个字节,所以第二个元素是4,第三个元素是8。这是java调用.net时,传入和读取数组时需要注意的事项。 Java与。Net类型匹配。 Api里的除字符串外的指针类型,对应jnative的pointer。 Api里的int、float等基本类型和String类型,在java中必须指定类型(Type.INT) Api里的date,是用int[]表示的,详见上条。 传值与返回值。 Jnative对象调用invoke后会有返回,对照api,一般返回值是调用状态。如果要查询一个测点值,返回值是通过传入的pointer对象读取出来的。 |
源代码如下:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern;
import org.xvolks.jnative.JNative; import org.xvolks.jnative.Type; import org.xvolks.jnative.exceptions.NativeException; import org.xvolks.jnative.pointers.Pointer; import org.xvolks.jnative.pointers.memory.HeapMemoryBlock; import org.xvolks.jnative.pointers.memory.MemoryBlock; import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
/** * Java通过jnative调用pi实时数据库dll类库piapi32.dll获取tag标签数据 * */ public class PIClientUtil { private static PIClientUtil piClientUtil=new PIClientUtil();
public static void main(String[] args) { //PIClientUtil.getPIClientUtil().getTimeFromInt(""); //PIClientUtil.getPIClientUtil().getTagValue("picompress_Compression Ratio_CALC"); //PIClientUtil.getPIClientUtil().getTagValueByTime("CDT158","2012-05-17 11:11:11"); //PIClientUtil.getPIClientUtil().getTagValuesByTimeToTime("CDT158","2012-05-17 11:11:11","2012-05-17 18:00:00",2); PIClientUtil.getPIClientUtil().getTagMaxValue("CDT158","2012-05-17 11:11:11","2012-05-17 18:00:00"); //PIClientUtil.getPIClientUtil().getTimeSecint(1); //PIClientUtil.getPIClientUtil().getPiTime(""); //PIClientUtil.getPIClientUtil().getTimeIntSec("2012-03-03 12:00:00"); }
public static PIClientUtil getPIClientUtil(){ return piClientUtil; }
private PIClientUtil() { try { // *********************连接PI数据库**************************// // **********************************************************// JNative messageBox = new JNative("piapi32.dll", "piut_setservernode"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.STRING, "127.0.0.1");//服务器ip messageBox.invoke();
System.out.println("piut_setservernode:"+messageBox.getRetValAsInt());
} catch (NativeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); }
} /** |