最近公司组织培训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数据库测点值相关推荐

  1. java读取pi_java读取PI数据库测点值

    java读取PI数据库测点值 JNative messageBox = new JNative("piapi32.dll", "pitm_parsetime") ...

  2. java读取ACCESS数据库的简单示例

    java读取ACCESS数据库的简单示例  虽然简单,对初学者来说,如果没有一段可以成功执行的代码供参考,还真难调试  先用ACCESS建一个数据库 DB1.MDB,里面有一表"table1 ...

  3. Java 访问PI 数据库:(1)安装必要软件

    Java 访问PI 数据库 需求 使用java 去访问PI 数据库 前提环境 已经在远程安装了PI 数据库. windows 系列 jre 8 及以上 资料收集 PI 官网 https://techs ...

  4. java读取mysql数据库配置文件_java读取properties文件的方法

    Java 读写Properties配置文件 Java 读写Properties配置文件 1.Properties类与Properties配置文件 Properties类继承自Hashtable类并且实 ...

  5. Java 访问PI 数据库:(2)JDBC访问PI

    技术说明 采用 Maven 集成 从 PI JDBC Driver 安装后的目录下取出 PIHOME\JDBC\PIJDBCDriver.jar.将其放在项目的lib 下,引入项目中 <!-- ...

  6. java 读取mysql数据库_原生Java操作mysql数据库过程解析

    这篇文章主要介绍了原生Java操作mysql数据库过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.引入数据库驱动的jar包 以通过mav ...

  7. Java 读取Oracle数据库中的Date日期型怎么去掉秒后面的0

     Oracle数据去0 分享方法 :为什么多了一个0,数据库里面的数据是没有0的,取出来的时候多了一个0,这是Oracle数据搞的鬼,解决代码如下 可参考 [java] view plaincop ...

  8. java 读取db3 数据库_db4o(db3文件是什么数据库)

    您好,db4o 几乎无法对应于现有的 Oracle.SQLServer 或 DB2!完全正确.相比之下,db4o 更适合于 MySQL 或 HSQL,这使其对于大量项目来说已经足够.更为重要的. 一. ...

  9. java 连接 Pi数据库——piapi方式

    环境: windows 32位jdk (1.7,1.8 测试通过) piapi32.dll (数据库安装后可找到) jna <dependency><groupId>net.j ...

最新文章

  1. 【ACM】POJ 1664
  2. chords(1)最初
  3. C++11 类型推导decltype
  4. 通信系统之数字复接技术
  5. MVC:开发模式及其优缺点
  6. MyBatis 插件原理与自定义插件-应用场景分析
  7. 程序员面试金典 - 面试题 17.18. 最短超串(双指针+哈希)
  8. python读取csv文件_Hello,Python!小鲸教你Python之文件读取
  9. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)签到题K Co-prime Permutation,L Let‘s Play Curling
  10. 计算机视频解码测试,无底限测试 入门电脑挑战H.265视频解码
  11. 打印纸张尺寸换算_常用纸张尺寸大小对照表
  12. web页面播放实时视频流
  13. 全国省市拼音数据json
  14. JavaWeb-仿小米商城(1) 项目启动
  15. 2.2 法力池的创建和视觉特效———自制卡牌游戏之旅
  16. 公众号文章中怎样图文排版可以实现逐行显示?
  17. 基于Django的博客BBS项目
  18. Cesium中获取地形三角网并进行土方计算
  19. Flowable入门系列文章11 - Flowable API 01
  20. excel切片器联动

热门文章

  1. 刚入行大数据的海归分享他的工作经历
  2. 原成都传智播客团队启用新品牌名源代码教育
  3. POSTGRESQL 从越来越多的ORACLE DBA 考取 PG 证书, 回顾2019- 2022
  4. jupyter lab安装、配置教程
  5. Python 对象引用、可变性和垃圾回收
  6. 老夫花了 3 天时间整理了一份史上最强 Java 学习路线图,送给有缘人!
  7. 计算机专业毕业,有人Offer 50w,有人挂科重修!
  8. 基于python的Opencv项目实战(第二章)
  9. 项目介绍——对话式教学系统
  10. AltiumDesigner 设置焊盘在钢网上是否开孔的办法