java通过piapi动态库操作PI数据库(2.x版本)实例

最近良哥在开发某电厂数据分析平台时需要操作PI数据库(OSIsoft公司的实时数据库产品),从PI 官网(https://techsupport.osisoft.com/)介绍可知,常用的访问PI数据库的方案有:①使用PI JDBC Driver或 ODBC Driver;②使用PI WEB API;③使用PI SDK;

一、使用 PI JDBC Driver

PI的JDBC驱动程序是一个java数据库连接驱动,通过SQL查询提供了强大的数据访问PI系统 。PI JDBC Driver 提供了一个类似于java 访问Mysql或者Oracle 同样的方式。但是,JDBC Driver 是 通过中间层 PI SQL DATA Access Server 来实现 PI JDBC driver 和 PI OLEDB Enterprise/PI OLEDB providers 之间的交互的。因此需要同时安装jdbc驱动和PI SQL DAS。

二、使用 PI WEB API

PI Web API是一个RESTful API,允许你通过HTTP请求与PI System进行交互。Java应用程序可以使用HTTP客户端库(如Apache HttpClient或OkHttp)来调用PI Web API。此方案是最便捷的,但是据厂家技术人员反馈,该方式只支持3.x版本以上的PI数据库。由于良哥此次面临的PI数据库是2.x版本,因此该方案无效。

三、使用 PI SDK

前言

此方案由于需要调用OSIsoft提供的piapi32.dll动态库,因此只能在windows系统上实现,同时对于c语言实现的库函数,java在调用时也需要完成变量类型的适配工作。以下主要详述此方案的具体实现方法。

1)环境:

操作系统:windows(linux不适用)
jdk版本:jdk1.8-32位(一定要32位版本,否则无法调用动态库)
PI接口库函数:piapi32.dll
下载地址1:https://download.youkuaiyun.com/download/hualinger/90414712
下载地址2:https://download.youkuaiyun.com/download/hualinger/90414696

2)POM引用(SpringBoot环境):

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.5.0</version>
</dependency>

3)代码示例

import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.ptr.IntByReference;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class PIAPITestUtils {

    @Test
    public void testPIDB() {
        PIAPILibrary api = PIAPILibrary.INSTANCE;//Dll实例
        // 连接服务
        System.out.println(api.piut_setservernode("192.168.0.109"));
        System.out.println(api.pitm_systime());

        // 获取位号“CDM158”的实时数据
        // 1.定义变量
        IntByReference pt = new IntByReference();
        IntByReference timedate = new IntByReference();
        FloatByReference rval = new FloatByReference();
        IntByReference istat = new IntByReference(0);
        // 2.调用接口获取数据
        System.out.println(api.pipt_findpoint("CDM158", pt));
        System.out.println(api.pisn_getsnapshot(pt.getValue(), rval, istat, timedate));
        // 3.输出结果
        System.out.println(pt.getValue());
        System.out.println(rval.getValue());
        System.out.println(istat.getValue());
        System.out.println(timedate.getValue());
    }
}

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.ptr.IntByReference;

public interface PIAPILibrary extends Library {

    PIAPILibrary INSTANCE = (PIAPILibrary) Native.loadLibrary("piapi32", PIAPILibrary.class);
    // piapi32中的接口 见piapi.h
    int piut_setservernode(String servername);
    int pitm_systime();

    // 查找tagname指定的位号并存入pt中
    // PIINT32 pipt_findpoint( char PIPTR *tagname, int32 PIPTR *pt );
    int pipt_findpoint(String tagname, IntByReference pt);

    // 获取PI时间
    // 这个函数解析传入的时间字符串并返回pi本地时间。如果传递的字符串是相对时间,则使用reltime作为计算绝对时间的起点。
    // 如果时间字符串有效则返回0,如果无效则返回-1。有效的时间字符串是一种绝对格式,包含dd-mm -yy hh:mm:ss、+|- n和|h|m|s格式的相对时间、
    // 用单词指定的绝对时间(今天、昨天、星期天、星期一、…)、用星号表示当前时间,或者使用单词绝对时间和相对时间之一的组合时间。
    // PIINT32 pitm_parsetime( char PIPTR *str, int32 reltime, int32 PIPTR *timedate);
    int pitm_parsetime(String timestr, int reltime, IntByReference timedate);

    // 获取timedate时间位号pt的值并存入rval、istat中
    // 这个函数检索发送到pi系统的特定点的最新值。返回快照的工程单位值、状态码、时间和日期。
    // 如果点类型不是实数,则以istat形式返回值,而rval参数返回为0。
    // PIINT32 pisn_getsnapshot( int32 pt, float PIPTR *rval, int32 PIPTR *istat, int32 *timedate );
    int pisn_getsnapshot(int pt, FloatByReference rval, IntByReference istat, IntByReference timedate);

    // 写入位号pt在时间timedate的值
    // PIINT32 pisn_putsnapshot( int32 pt, float rval,  int32 istat, int32 timedate );
    int pisn_putsnapshot(int pt, float rval, int istat, int timedate);

    // 写入位号pt的值rval、istat、timedate、wait
    // PIINT32 piar_putvalue( int32 pt, float rval, int32 istat, int32 timedate, int32 wait );
    int piar_putvalue(int pt, float rval, int istat, int timedate, int wait);

    //这个函数检索服务器上定义的所有单位。第一次调用该函数时,应该将Index设置为0,随后的调用应该将Index增加到number-1,以检索剩余的单元名称。
    // int32 piba_getunit( char PIPTR * unit, int32 len, int32 index,  int32 PIPTR * number );
    int piba_getunit(String unit, int len, int index, IntByReference number);
}

4)运行结果:

在这里插入图片描述

5)其他

  • 映射参数设置

1):基本类型 直接找java中与之对应的类型转换即可
2):指针类型 转换如下

c语言函数:PIINT32 pisn_getsnapshot( int32 pt, float PIPTR *rval, int32 PIPTR *istat, int32 *timedate );
java映射:int pisn_getsnapshot(int pt, FloatByReference rval, IntByReference istat, IntByReference timedate);

3)jna对结构体、指针、引用、拷贝参数传递的使用参考:https://blog.youkuaiyun.com/xie_heng/article/details/49814207

  • 库函数介绍

在这里插入图片描述

详见帮助文档:
下载地址1:https://download.youkuaiyun.com/download/hualinger/90414712
下载地址2:https://download.youkuaiyun.com/download/hualinger/90414696

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值