Java读取PI数据库测点值

安装数据库

安装osi ,启动PIPerfMon_Basic.bat,使用process book 绘制一个趋势图,加入几个例子测点,如“CDT158”,如图:

java调用小冰 java调用pi_java调用小冰

  1. Piapi简介

利用PIAPI直接操作PI,安装PI数据库后会有一个piapi32.dll,提供了.net读取的接口。

  1. Jnative简介

JNative是一种能够使Java语言使调用DLL的一种技术,对JNI进行了封装。我们将下载的jnative.jar解压后,有一个jNativeCpp.dll,将其拷入C:\windows\system32下,并将jnative.jar加载到我们项目中来。准备工作就绪。

  1. 程序读取。要点记录:
  2. 阅读API。打开PI System->about PI SDK->View Help,即可看到api文档。
  3. PI数据库的数据分别存储在Snapshot或者Archive中,一个是快照一个是档案文件,这样做是为了方便PI数据库对数据进行压缩.那么自然对数据库的读取也分为对Snapshot和Archive读取.snapshot和archive的值都是用PIValue的形式表示的, PIValue对象包括了数值和时间。
  4. 其中Pi的api中,用到最多的函数组是time functions、archive functions、snapshot functions。time functions包含很多对时间处理的函数; archive functions包含了对档案文件的读写的函数;snapshot functions包含了对快照的读取函数。
  5. 时间处理。
  6. .net调用piapi传入时间类型时,是将.net的Date类型转为int数组,并可以直接将int数组传入方法。Java使用时间类型稍微复杂一些,需要调用pitm_intsec方法,该方法帮助如下:
  7. PIVOID pitm_intsec(
  8. int32 PIPTR * timedate,
  9. int32 timearray[6] );

  10. Returns

  11. None

  12. Arguments

  13. timedate (returned)

  14. PI time stamp

  15. timearray (passed)
  16. 表示该方法2个参数,第一个是一个int型数组(指针),第二个参数是一个int型数组。第一个参数是返回参数,第二个参数是传入参数。
  17. 注意,传入int32 timearray[6]参数时,必须使用Pointer模拟指针,并且,循环设置数组元素时,注意pointer.setIntAt(int offset, int value),offset的下标,比如第一个元素是0,第二个元素不是1,要看int占几个字节,int在。Net中占4个字节,所以第二个元素是4,第三个元素是8。这是java调用.net时,传入和读取数组时需要注意的事项。
  18. Java与。Net类型匹配。
  19. Api里的除字符串外的指针类型,对应jnative的pointer。
  20. Api里的int、float等基本类型和String类型,在java中必须指定类型(Type.INT)
  21. Api里的date,是用int[]表示的,详见上条。
  22. 传值与返回值。
  23. 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;

   }
}