






















上次说了这次的题目是对PI数据库中的数据进行读取和写入,可是为了等了这么久呢?出了自己比较懒以外,遇到了一点麻烦也是一个原因呢?后面又说
(一)应用SDK从PI数据库读取数据
我们知道PI数据库的数据分别存储在Snapshot或者Archive中,一个是快照一个是档案文件,这样做是为了方便PI数据库对数据进行压缩.那么
自然对数据库的读取也分为对Snapshot和Archive读取.snapshot和archive的值都是用PIValue的形式表示的,
PIValue对象包括了数值和时间。应用SDK从数据库中获取snapshop或者archive的值很简单。
首先连接数据库,声明一个PIServer:_piServer = piSDK.Servers.DefaultServer;
然后利用PIServer的Points属性访回一个点的集合,再通过tagName来获取点:PIPoint pt = _piServer.PIPoints[tbxTagName.Text];
如果是使用Snapshot,直接声明一个PIValue通过PIPoint的Snapshot属性来返回值:pv = pt.Data.Snapshot;
然后我们就可以通过PIValue的Value属性和TimeStamp属性来获取snapshot的值和该值对应的时间了。
tbxValue.Text = pv.Value.ToString();
tbxTime.Text = pv.TimeStamp.LocalDate.ToString();
如果要读取Archive的值,那么要稍微麻烦一点,应为你要给定读取的时间和模式,PIPoint对象的ArcValue方法是用来获取Archive的值,帮助的说明如下:
object.ArcValue
TimeStamp, Mode, AsynchStatus
这
个应该是VB的语法吧,我们可以看出他有三个参数。第一个是时间,C#中我们可以直接传一个DateTime格式的数据进去,当然你也可以使用
PITime对象表示的时间,或者一个字符串。Mode代表取出的模式,因为PI数据库并不是每个时间都存有数据的,所以在你可以选择模式是读取你输入时
间的当前点,后面一个点,前面一个点或者插值表示的时间。最后一个参数不解,文档里面没有说明,VB的例子则直接没有传这个参数,应该是一个可选参数,我
的处理方法如下。
RetrievalTypeConstants rtType;
rtType = (RetrievalTypeConstants)piSDK.PIConstants["RetrievalTypeConstants"][cbxValue.Text].Value;
pv = pt.Data.ArcValue(dt, rtType, new PISDKCommon.PIAsynchStatus());
RetrievalTypeConstants 就是表示存取模式的,我这里使用过一个下拉列表框获得可用的模式的,最后一个参数是通过传一个新的实例下去,这里不知道这样和不合理,反正可以读出数据我就没有管了,又没有达人解释一下怎么处理这种VB的可选参数的情况呢?我学着VSTS的那种Type.Missing又不可以。
然后读出来的PIValue同样包含一个数值和一个时间,现在我想大家应该理解为什么PIValue里面要包含一个时间了吧。
我觉得应用SDK很简单,感觉和开发Excel很象,都是调用Com,也挺符合.net的开发习惯的,文档也好,每个对象还有一个详细的VB例子,虽然不是.net的,但是也可以大致了解得差不多。
(二)应用SDK向PI数据库写入数据
在PIData对象中有一个
Not Implemented两个单词,心顿时凉了,考虑到文档的版本比我实际使用的SDK版本第一点,去Object Browser里面搜索了一下,果然找到了这个方法
public
virtual void UpdateValue(object newValue, object TimeStamp,
PISDK.DataMergeConstants MergeType, PISDKCommon.PIAsynchStatus
asynchStatus)
这些参数的意思没有文档也挺好理解的,这里就不说了,可是当我尝试用这个方法去更新数据库的时候,一样抛出了Not Implemented的错误,当时心里非常的郁闷,这个也就是开头我说到的麻烦。我的SDK的版本是1.2.0,问了一个比较有经验的人,他说他没有遇到过不能写入的问题,等有时间去问问他,看看是不是版本的问题,如果有人能写入的,请给我说一下你们的版本;
(三)应用API从PI数据库读取数据
SDK不行,还好我们还有PI-API,这个感觉和Win32 API挺象的吧,都是一写用C写的函数,PISDK其实就是把PIAPI包装了一下,可惜我对P/Invoke不怎么熟悉,如果大家对这个也不熟悉的话,我觉得这两篇文章还是不错,作为预备知识。
Data quality flag mask不解。time是值对应的时间,相当于SDK里面的pv.TimeStamp.LocalDate。
对于字符串,这里我看了半天,因为string类型是一个不定长的字符串,所以是不能用在这个地方的,这个地方的bval应该是使用 StringBuilder,StringBuilder.Capacity就表示了bsize,这一点还是冲上面那两篇文章看到的,真是基础差,呵呵。
对于void指针,我是把它处理成为object类型,因为我们基本上不用到字符串的值,所以这里我也没有测试,达人指导一下,呵呵。综上,我的C#格式的函数是
[DllImport("piapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 piar_getarcvaluex(
Int32 ptnum,
Int32 mode,
ref Double drval,
ref Int32 ival,
[MarshalAs(UnmanagedType.AsAny)] object bval,
ref UInt32 bsize,
ref Int32 istat,
ref Int16 flags,
ref PITime.PITIMESTAMP time);
第五个参数必须Mashall成AsAny类型,要不直接使用object类型是不行的。那么我怎么知道他是Any类型呢?因为文档上面VB的函数调用声明是bVal As Any,这也是一点灵感吧。至于返回的Int32值是代表调用是否成功的,就和win32 API类似吧。
这次就先写到这里吧,下次待续
如果大家解决过我不解的问题,先写写了。呵呵!
***********************************************************************************************************************************
同上一篇,本文谢绝转载.包括网络和其他介质
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。