本文简单介绍OPC HDA规范的IOPCHDA_SyncRead接口方法,更多通信资源请登录网信智汇(wangxinzhihui.com)。
1)HRESULT ReadRaw (htStartTime, htEndTime, dwNumValues, bBounds, dwNumItems, phServer, ppItemValues, ppErrors)
此函数从历史数据库中读取一个或多个项目的指定时域的值、质量和时间戳。当bBounds为TRUE时,将返回时域的边界值。此功能旨在供希望在历史记录中保存实际数据的客户使用。实际数据可以被压缩,或者可以是为项目收集的所有数据,这取决于历史记录和保存项目值时调用的存储规则。提供可选的边界值以允许客户端在对显示器上的实际数据进行趋势分析时对开始和结束时间的值进行插值。
请求的时域由htStartTime、htEndTime和dwNumValues定义;必须至少指定其中两个。如果htEndTime小于htStartTime,或者只指定了htEndTime和dwNumValues,则数据将以相反的顺序返回,后面的数据将先返回。如果指定了这三个值,则调用将根据htStartTime和htEndTime的相对值以升序或降序返回从htStartTime到htEndTime最多dwNumValues的结果。如果dwNumValues为0,则返回该范围内的所有值。OPCHDA_TIME的空值用于指示未指定htStartTime或htEndTime。
如果htStartTime或htEndTime是以字符串(相对)格式给出的,则OPCHDA_time结构的绝对时间(ftTime)应设置为FILETIME,该FILETIME是服务器将相对时间转换为的。
特别允许htStartTime和htEndTime相同。这允许客户端只请求一个值。如果请求的时域超出服务器的范围,则特别不允许服务器返回E_INVALIDARG。这种情况应视为不存在数据的区间。
如果在该时间范围内存在多个dwNumValues结果,则该ItemID的ppErrors条目应为OPC_S_MOREDATA。当返回OPC_S_MOREDATA时,想要下一个dwNumValues值的客户端应再次调用ReadRaw,并将为该项返回的最旧值的时间戳作为新的htStartTime,同时保持htEndTime的原始值不变(如果需要相反的顺序,则反转htStartTime和htEndTime)。请注意,第二次调用将返回上一次调用中最后一个值的副本。
如果请求了边界值,并且指定了非零的dwNumValues,则返回的任何边界值都将包含在dwNumValue计数中。如果dwNumValues为1,则只返回起始边界(如果需要相反的顺序,则返回结束边界)。如果dwNumValues为2,则返回数据点和起始边界(如果需要相反的顺序,则返回结束边界)。
当请求边界值但未找到边界值时,ppItemValues中相应的数组元素的质量将为OPCHDA_NOBOUND,时间戳等于开始或结束时间(视情况而定),VARIANT的值为VT_EMPTY。在历史中查找边界值的前后距离取决于服务器。
如果只指定了htStartTime或htEndTime中的一个,并且指定了非零的dwNumValues,则历史上的最后一个值被视为结束界限(如果需要相反的顺序,则为开始界限)。
对于不存在数据的间隔,如果未请求或未找到边界值,则相应的ppErrors应为OPC_S_NODATA,而OPCHDA_Item的dwCount应为0。如果请求了边界值并且其中一个或两个都存在,则ppError返回为S_OK,并返回边界值。当然,如果任何ppError代码不是S_OK,则返回给客户端的HRESULT必须是S_FALSE。
2)HRESULT ReadProcessed (htStartTime, htEndTime, ftResampleInterval, dwNumItems, phServer, haAggregate, ppItemValues, ppErrors)
该方法可选。
该方法在标准的v1.0和v1.1之间进行了更改,以将haAggregate作为DWORD而非ENUM传递,从而允许供应商指定自己的聚合。使用该标准v1.0构建的服务器和客户端将与使用v1.1构建的服务器或客户端协同工作,但v1.0客户端可能与返回供应商指定聚合的v1.1服务器不兼容。
此函数根据历史数据库中一个或多个项目的指定时域的数据计算聚合值、质量和时间戳。时域被划分为持续时间为ftResampleInterval的子区间。通过使用下一个ftResampleInterval中的数据,为以htStartTime开始的每个子区间计算指定的haAggregate。
此函数旨在提供相对于重采样间隔计算的值。例如,当ftResampleInterval为1小时时,此函数可以为指定时域内的每个项目提供每小时统计信息,如Maximum、Minimum、Average等。
请求的域由htStartTime、htEndTime和htResampleInterval定义。如果htStartTime或htEndTime是以字符串(相对)格式给定的,则返回的值应为服务器将该值转换为的FILETIME。必须指定这三个。如果htEndTime小于htStartTime,则应以相反的顺序返回数据,后面的数据优先。如果htStartTime和htEndTime相同,则服务器应返回E_INVALIDARG,因为没有任何有意义的方法来解释这种情况。
用于计算每个子区间的聚合的值应包括正好落在子区间开始的时间戳上的任何值,但不应包括直接落在子间隔结束的时间戳的任何值。因此,每个值在计算中只能包含一次。如果时域的顺序相反,我们认为较晚的时间戳是子区间的开始时间,较早的时间戳则是子区间结束时间。请注意,这意味着简单地交换开始和结束时间不会导致以相反的顺序返回相同的值,因为在这两种情况下请求的子区间不相同。
如果计算的最后一个子区间不是完整的子区间(请求的时域不能被重新采样间隔整除),则返回的最后一个聚合应基于该不完整的子间隔,并且聚合的质量应为OPCHDA_PARTIAL。
对于MinimumActualTime和MaximumActualTime,如果一个子区间内存在多个值实例,则返回的值实例(时间戳)取决于服务器。在任何情况下,服务器可以设置OPCHDA_EXTRADATA质量标志,以使呼叫者知道存在具有该值的其他时间戳。
要获得同一项目的多个聚合,请在每个所需聚合的项目列表中包含服务器项目句柄。
如果htResampleInterval为0,则服务器应为整个时间范围创建一个聚合值。这允许在长时间内进行聚合。时间戳等于htEndTime的值将从该聚合中排除,就像它将从具有该结束时间的子区间中排除一样。
与聚合一起返回的时间戳应为间隔开始时的时间,除非聚合指定了不同的值。此外,如果聚合所依据的所有值的质量均为良好,则聚合返回的质量应为良好(见OPC数据访问标准)。如果这些值中的任何一个具有任何其他质量,则聚合的质量应为亚正常(0x010110xx)。
如果时域中的任何子区间中不存在给定项的数据,则服务器应在该项的ppErrors数组中返回OPC_S_NODATA,并且相应的ppItemValues结构的dwCount应为0。
如果该项的至少一个子区间中确实存在数据,则服务器应返回时域中每个子区间的时间戳、质量和值。对于没有数据的每个子区间,服务器应返回该子区间的VT_EMPTY值和OPCHDA_NODATA质量,并带有适当的时间戳。如果聚合的时间戳基于数据,则为OPCHDA_NODATA返回的时间戳应为间隔开始的时间戳。
注:供应商定义的聚合在子区间中是否包含后缘值方面可能具有不同的行为。预计服务器供应商将清楚地记录其供应商特定聚合的行为,以便客户端知道每个聚合中包含哪些值。
3)HRESULT ReadAtTime (dwNumTimeStamps, ftTimeStamps, dwNumItems, phServer, ppItemValues, ppErrors)
此函数从历史数据库中读取一个或多个项目的指定时间戳的值和质量。此函数旨在提供与具有已知时间戳的其他值相关的值。例如,收集实验室样本时传感器的值。
返回的值和质量的顺序应与请求中提供的时间戳的顺序相匹配。
当指定的时间戳不存在值时,应从周围的值中插入一个值,以表示指定时间戳的值。
OPCHDA_ITEM结构将在haAggregate字段中返回OPCHDA_NOAGGREGATE。
如果找到指定时间戳的值,服务器将在质量中设置OPCHDA_RAW位。如果该值是根据周围的值进行插值的,则服务器将在质量中设置OPCHDA_interpolated位。
4)HRESULT ReadModified(htStartTime, htEndTime, dwNumValues, dwNumItems, phServer, ppItemValues, ppErrors)
此函数从历史数据库中读取一个或多个项目的指定时域的修改值、质量、时间戳、用户ID和时间戳。如果ReadRaw、ReadProcessed或ReadAtTime返回的质量为OPCHDA_EXTRADATA,表示存在被取代的值,则此函数将允许您查看被取代的那些值。此函数只读取已修改/替换或删除的值。这是接口上的一个可选方法。
请求的域由htStartTime、htEndTime和dwNumValues定义;必须至少指定其中两个。如果htEndTime小于htStartTime,或者只指定了htEndTime和dwNumValues,则应以相反的顺序返回数据,后面的数据优先。如果指定了这三个值,则调用应根据StartTime和EndTime的相对值以升序或降序返回从StartTime到EndTime的最多dwNumValues结果。如果在该时间范围内存在多个dwNumValues结果,则该ItemID的ppErrors条目应为OPC_S_MOREDATA。如果dwNumValues为0,则返回该范围内的所有值。
如果一个值被修改了多次,则会返回该时间的所有值。这意味着时间戳可以多次出现在数组中。具有相同时间戳的返回值的顺序应该是从最近修改值到最旧修改值。是否保留多次修改或仅保留最近的修改取决于服务器。
5)HRESULT ReadAttribute (htStartTime, htEndTime, hServer, dwNumAttributes, pdwAttributeIDs, ppAttributeValues, ppErrors)
此函数从历史数据库中读取项目指定时域的属性值和时间戳。如果需要属性的当前值,则htStartTime应设置为“NOW”,htEndTime应为NULL。
此函数用于检索已更改的属性,以便将这些属性的值与其数据的值关联起来。例如,传感器的重新校准可能需要改变正常的最大和最小属性。
如果项目唯一可用的属性值是当前值,则应返回这些值,并将ppError设置为OPC_S_CURRENTVALUE。
除了请求当前值(htStartTime=NOW,htEndTime=NULL)的情况外,服务器应始终返回一个起始边界值。因此,如果客户端请求1997年1月1日至1997年10月1日的属性值,则服务器应在1997年1日返回该属性的值,而不是返回的第一个值是1997年1月份1日之后该属性的第一个新值。同样,第一个值的时间戳应为1997年1月1日,而不管属性实际何时取该值。所有其他时间戳应为属性值发生变化的时间。
请注意,虽然客户端可以向服务器查询ItemID的本机数据类型,但客户端不能假设从服务器发送的所有数据都是该数据类型。给定ItemID的数据类型可能在Item的使用寿命内发生了变化,因此客户端应该能够处理接收与此调用返回的数据类型不同的数据类型的数据。
未完待续。更多通信资源请登录网信智汇(wangxinzhihui.com)。