- 浏览: 10029 次
- 性别:
- 来自: 济南
最新评论
最近公司组织培训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(); }
} /** * 获取tag最新值 * @param tagName * @return */ public float getTagValue(String tagName){ try {
JNative messageBox = new JNative("piapi32.dll", "pipt_findpoint"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.STRING, tagName); Pointer p=new Pointer(new HeapMemoryBlock(1024)); messageBox.setParameter(1, p); messageBox.invoke(); int ptId=p.getAsInt(0); if(0==messageBox.getRetValAsInt()){ System.out.println("测点id:"+ptId); messageBox = new JNative("piapi32.dll", "pisn_getsnapshot"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.INT, "" + ptId); Pointer pp=new Pointer(new HeapMemoryBlock(1024)); messageBox.setParameter(1, pp); messageBox.setParameter(2, new Pointer(new HeapMemoryBlock(1024))); //messageBox.setParameter(3, new Pointer(new HeapMemoryBlock(1024))); //messageBox.setParameter(4, new Pointer(new HeapMemoryBlock(1024))); messageBox.invoke(); if(0==messageBox.getRetValAsInt()){ System.out.println(tagName+"测点值:"+pp.getAsFloat(0)); return pp.getAsFloat(0); }
}else{ System.out.println("查询测点失败"); }
} catch (NativeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 0F; }
/** * 获取测点制定时间点的值 * @param tagName * @return */ public float getTagValueByTime(String tagName,String time){
try {
JNative messageBox = new JNative("piapi32.dll", "pipt_findpoint"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.STRING, tagName); Pointer p=new Pointer(new HeapMemoryBlock(8)); messageBox.setParameter(1, p); messageBox.invoke(); int ptId=p.getAsInt(0); if(0==messageBox.getRetValAsInt()){ System.out.println("测点id:"+ptId); messageBox = new JNative("piapi32.dll", "piar_value"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.INT, "" + ptId); Pointer pp=new Pointer(new HeapMemoryBlock(1024)); Pointer pp_status = new Pointer(new HeapMemoryBlock(1024)); messageBox.setParameter(1,getTimeIntSec(time)); messageBox.setParameter(2, Type.INT,3+""); messageBox.setParameter(3, pp); messageBox.setParameter(4, pp_status); messageBox.invoke(); if(0==messageBox.getRetValAsInt()){ System.out.println(tagName+"测点值:"+pp.getAsFloat(0)); System.out.println(tagName+"status值:"+pp_status.getAsInt(0)); return pp.getAsFloat(0); }else{ System.out.println(tagName+"查询返回值:"+messageBox.getRetValAsInt()); }
}else{ System.out.println("查询测点失败"); }
} catch (NativeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 0F; }
/** * 查询测点某时间段内最小值 * @param tagName * @param time1 * @param time2 */ public void getTagMinValue(String tagName,String time1,String time2){ int code = 1; this.getTagValuesByTimeToTime(tagName, time1, time2, code); }
/** * 查询测点某时间段内最大值 * @param tagName * @param time1 * @param time2 */ public void getTagMaxValue(String tagName,String time1,String time2){ int code = 2; this.getTagValuesByTimeToTime(tagName, time1, time2, code); } /** * 查询测点某时间段内平均值 * @param tagName * @param time1 * @param time2 */ public void getTagAvgValue(String tagName,String time1,String time2){ int code = 5; this.getTagValuesByTimeToTime(tagName, time1, time2, code); }
/** * * @param tagName * @return */ public void getTagValuesByTimeToTime(String tagName,String time1,String time2, int code){
try {
JNative messageBox = new JNative("piapi32.dll", "pipt_findpoint"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.STRING, tagName); Pointer p=new Pointer(new HeapMemoryBlock(1024)); messageBox.setParameter(1, p); messageBox.invoke(); int ptId=p.getAsInt(0); if(0==messageBox.getRetValAsInt()){ System.out.println("测点id:"+ptId); messageBox = new JNative("piapi32.dll", "piar_summary"); messageBox.setRetVal(Type.INT); //下面开始设置参数 messageBox.setParameter(0, Type.INT, "" + ptId);
Pointer p_startTime = this.getTimeIntSec(time1); Pointer p_endTime = this.getTimeIntSec(time2);
Pointer p_retVal = new Pointer(new HeapMemoryBlock(8));
Pointer p_pctGood = new Pointer(new HeapMemoryBlock(8));
messageBox.setParameter(1, p_startTime); messageBox.setParameter(2, p_endTime); messageBox.setParameter(3, p_retVal); messageBox.setParameter(4, p_pctGood); messageBox.setParameter(5, Type.INT,code+""); messageBox.invoke(); if(0==messageBox.getRetValAsInt()){ System.out.println(tagName+"测点返回值:"+p_retVal.getAsFloat(0)); }else{ System.out.println(tagName+"查询状态值:"+messageBox.getRetValAsInt()); }
}else{ System.out.println("查询测点失败"); }
} catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }
/** * 将时间串转换为int * 格式:11-Aug-17 18:00:00 * @param time * @return */ public int getPiTime(String time){ // 获取时间点 try { String tt = time; Pointer pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(8));
JNative messageBox = new JNative("piapi32.dll", "pitm_parsetime"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.STRING, tt); messageBox.setParameter(1, Type.INT, "0"); messageBox.setParameter(2, pointer); messageBox.invoke(); if(0 == messageBox.getRetValAsInt()){ System.out.println("执行成功,getPiTime结果是:"+ pointer.getAsInt(0)); return pointer.getAsInt(0); }else{ System.out.println("执行失败"); return 0; } } catch (NativeException e) { e.printStackTrace(); return 0; } catch (IllegalAccessException e) { e.printStackTrace(); return 0; } }
/** * 将整数转换为时间,同上方法互逆 * @param time * @return */ public String getTimeFromInt(int time){
try { Pointer pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(8));
JNative messageBox = new JNative("piapi32.dll", "pitm_formtime"); messageBox.setRetVal(Type.INT); messageBox.setParameter(0, Type.INT,this.getPiTime("")+""); messageBox.setParameter(1, pointer); messageBox.setParameter(2,19); messageBox.invoke();
System.out.println("结果是:"+ pointer.getAsString()); return pointer.getAsString(); } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return ""; }
/** * 将PI日期转为数组型 * @param time * @return */ public int[] getTimeSecint(int time){ int [] time_arrays = new int[6]; try { Pointer pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(4* time_arrays.length)); JNative messageBox = new JNative("piapi32.dll", "pitm_secint");
messageBox.setParameter(0, Type.INT,this.getTimeIntSec("2012-05-17 11:11:11").getAsInt(0)+""); messageBox.setParameter(1, pointer); messageBox.invoke();
for(int i=0;i<time_arrays.length;i++){ time_arrays[i] = pointer.getAsInt(i*4); }
return time_arrays; } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; }
/** * 将日期转为数组型,与pitm_secint互相逆 * @param time * @return */ public Pointer getTimeIntSec(String time){
PIDate date = PIDate.getPIDate(time); try {
int time_array[] = new int[]{date.getMonth() , date.getDay() , date.getYear() , date.getHour(), date.getMinutes(), date.getSeconds()};
Pointer pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(8)); Pointer pointer_array = new Pointer(MemoryBlockFactory.createMemoryBlock(time_array.length*4)); JNative messageBox = new JNative("piapi32.dll", "pitm_intsec"); /**这种方法也可以 pointer_array.setIntAt(0, 2012); pointer_array.setIntAt(4, 5); pointer_array.setIntAt(8, 16); pointer_array.setIntAt(12, 21); pointer_array.setIntAt(16, 33); pointer_array.setIntAt(20, 33); **/
// 初始化数组 for (int i = 0;i < time_array.length; i++) { pointer_array.setIntAt(4 * i, time_array[i]); }
messageBox.setParameter(0, pointer); messageBox.setParameter(1, pointer_array); messageBox.invoke(); System.out.println("getTimeIntSec="+pointer.getAsInt(0)); return pointer; } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; }
/** * 不能直接返回int[0] * @param time * @return */ public int getTimeIntSecForInt(String time){ PIDate date = PIDate.getPIDate(time); try {
int time_array[] = new int[]{date.getMonth() , date.getDay() , date.getYear() , date.getHour(), date.getMinutes(), date.getSeconds()}; Pointer pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(8)); Pointer pointer_array = new Pointer(MemoryBlockFactory.createMemoryBlock(time_array.length*4)); JNative messageBox = new JNative("piapi32.dll", "pitm_intsec");
// 初始化数组 for (int i = 0;i < time_array.length; i++) { pointer_array.setIntAt(4 * i, time_array[i]); }
messageBox.setParameter(0, pointer); messageBox.setParameter(1, pointer_array); messageBox.invoke(); System.out.println("getTimeIntSec="+pointer.getAsInt(0)); return pointer.getAsInt(0); } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return 0; }
}
|
时间工具类:
import java.util.regex.Matcher; import java.util.regex.Pattern;
public class PIDate { private int year; private int month; private int day; private int hour; private int minutes; private int seconds;
public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getHour() { return hour; } public void setHour(int hour) { this.hour = hour; } public int getMinutes() { return minutes; } public void setMinutes(int minutes) { this.minutes = minutes; } public int getSeconds() { return seconds; } public void setSeconds(int seconds) { this.seconds = seconds; }
public static PIDate getPIDate(String time){ Pattern p=Pattern.compile("(\\d{4})-(\\d{1,2})-(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})"); Matcher m=p.matcher(time); PIDate date = new PIDate(); if(m.find()){ /*System.out.println("日期:"+m.group()); System.out.println("年:"+m.group(1)); System.out.println("月:"+m.group(2)); System.out.println("日:"+m.group(3)); System.out.println("时:"+m.group(4)); System.out.println("分:"+m.group(5)); System.out.println("秒:"+m.group(6));*/ date.setYear(Integer.parseInt(m.group(1))); date.setMonth(Integer.parseInt(m.group(2))); date.setDay(Integer.parseInt(m.group(3))); date.setHour(Integer.parseInt(m.group(4))); date.setMinutes(Integer.parseInt(m.group(5))); date.setSeconds(Integer.parseInt(m.group(6))); } return date;
} } |
相关推荐
Java 读取 PI 数据库测点值 Java 读取 PI 数据库测点值是指使用 Java 语言直接读取 PI 数据库中的测点值。PI 数据库是 OSIsoft 公司开发的一种工业数据管理系统,广泛应用于工业自动化、能源、交通、医疗等领域。 ...
java通过调用dll的方式连接pi数据库,需要用piapi32.dll,我将2个dll都打包好了,供大家使用,分数不高,完全就是为了方便大家。我已经测试通过。必须是可以用的,真的好难啊。不容易啊,连接pi数据库,真费劲啊。
本教程将详细讲解如何利用C#编程语言通过PI SDK读取PI数据库中的实时、历史以及极值数据。 首先,我们需要引入必要的PI SDK库到C#项目中。这通常涉及在解决方案资源管理器中右键点击“引用”并选择“添加引用”,...
通过ODBC方式,从PI数据库取出测点实时数据,转存到SQLSERVER数据库中
在工业自动化领域,PI(ProcessBook)数据库是一个广泛使用的实时和历史数据管理平台,由OSIsoft公司开发。...通过深入理解并运用这些知识点,你可以构建出强大的PI数据库应用,实现高效的数据读取和处理。
C#使用PISDK连接PI数据库,获取测点、历史数据、快照数据
PI实时数据库API是 OSIsoft 公司开发的一种接口库,用于与PI系统进行交互,它提供了丰富的函数和方法,使得开发者能够高效地读取、写入、处理PI系统的实时和历史数据。标题中的"piapi.dll"是这个API的核心组件,主要...
《PI数据库采集程序详解》 PI数据库,全称为Process Historian,是由OSIsoft公司开发的一款实时历史数据库系统,主要用于存储、管理和分析工业过程数据。PI数据库的强大在于其高效的性能和丰富的接口,使得用户能够...
之前查了很多关于用C#连接PI数据库的方法,感觉代码说的都不是很清楚。我自己写了一个很简单的代码,也不用封装类,就是在main函数里面连接SDK,并输入相应的测点,然后显示相应的值和时间
知识点: 1、读PI数据库 2、结合DATASET对XML进行读写操作 3、Time类的运用 要运行此程序须具备以下条件: 1、具有PI数据库 2、XML文件中所列的测点在PI数据库中存在 3、程序开发环境为:visual studio 2010
这些DLL文件包含了必要的接口和方法,允许开发者通过C#代码读取、写入、查询PI实时库的数据,执行复杂的计算,以及触发事件等操作。使用这些库,开发者可以构建定制化的监控和报警系统、数据分析应用或者其他与PI...
例如,在河南天冠燃料乙醇有限公司的MES系统中,PI实时数据库与多套控制系统相连,处理超过两万个测点的数据,显著提升了企业的信息化管理水平。 PI数据库的安装部署通常基于Client/Server架构,支持Windows和UNIX...
IHUAPI提供了丰富的功能,包括但不限于连接到数据库、设置和获取测点信息、读取和修改测点的数值等。 1. **连接到IHistorian数据库**: 使用IHUAPI,开发者可以通过C#编写代码来建立到IHistorian服务器的连接。这...
这个工具特别针对 PI Asset Framework (PI AF) 数据库和 PI Server 中的 PI 标记点提供了创建、查看和编辑功能,极大地提升了数据管理和分析的效率。 **PI Builder 概述** PI Builder 的主要功能包括: 1. **对象...
OSIsoft PI System 培训教程 PPT 涉及: PI 架构 PI 客户端工具 PI 测点 PI 接口 PI 系统管理 PI SDK使用 PI ProcessBook PI DataLink PI config PI 安全性
PI实时数据库目前整合了1#和2#发电机组的生产数据、关口表电量数据及状态监测数据,设有10G的数据存储空间,包含9000个测点Tag。 在通信接口技术方面,系统与Westhouse WDPF控制系统对接,通过两台PC作为接口机,...
### PI实时数据库与MAXIMO系统数据交换方案原理 #### 需求背景及意义 MAXIMO作为电力行业中资产管理的核心软件,对于电力设施的维护管理至关重要。随着技术的发展,电力企业正逐渐从传统的计划检修和预防性维修...
osisoft datalink 是在excel中取pi测点值的插件,这是完整的vba代码,来自osisoft,需要piapi的支持,欢迎大家交流pi的各种相关技术,大家共同提高