- Posts: 35
- Thank you received: 1
Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
- Forum
- Discussions
- QuickOPC-Classic in COM
- Reading, Writing, Subscriptions, Property Access
- QuickOPC VBScript ASP example script not returning value
QuickOPC VBScript ASP example script not returning value
- Kyle.Oshima@caltrol.com
- Topic Author
- Offline
- Platinum Member
<!--$$Header: $-->
<!-- Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. -->
<!---->
<!--Find all latest examples here : opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .-->
<%@ LANGUAGE="VBSCRIPT" %>
<html><head><t-itle>ReadAndDisplayValue_VBScript.asp</title></head>
<body>
<%
' Selects the data source for OPC reads (from device, from OPC cache, or dynamically determined).
' The data source (memory, OPC cache or OPC device) selection will be based on the desired value age and current status of
' data received from the server.
Const DADataSource_ByValueAge = 0
' OPC reads will be fulfilled from the cache in the OPC server.
Const DADataSource_Cache = 1
' OPC reads will be fulfilled from the device by the OPC server.
Const DADataSource_Device = 2
Dim ReadItemArguments1: Set ReadItemArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments1.ServerDescriptor.ServerClass = "DeltaV.DVSYSsvr.1"
ReadItemArguments1.ItemDescriptor.ItemID = "THISUSER/USERNAME.A_CV"
ReadItemArguments1.ReadParameters.DataSource = DADataSource_Device ' read will be from device
Dim arguments(0)
Set arguments(0) = ReadItemArguments1
' Create EasyOPC-DA component
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
' Specify that only synchronous method is allowed. By default, both synchronous and asynchronous methods are allowed, and
' the component picks a suitable method automatically. Disallowing asynchronous method leaves only the synchronous method
' available for selection.
Client.InstanceParameters.Mode.AllowAsynchronousMethod = False
Dim results: results = Client.ReadMultipleItems(arguments)
Dim i: For i = LBound(results) To UBound(results)
Dim VtqResult: Set VtqResult = results(i)
If VtqResult.Succeeded Then
Response.Write "results(" & i & ").Vtq.ToString(): " & VtqResult.Vtq.ToString()
Else
Response.Write "results(" & i & ") *** Failure: " & VtqResult.ErrorMessageBrief
End If
Next
' Read item value and display it
' Note: An exception can be thrown from the statement below in case of failure. See other examples for proper error
' handling practices!
' Response.Write Client.ReadItemValue("", "OPCLabs.KitServer", "Demo.Single")
%>
</body>
</html>
re: test the same VBScript (with just modified output code) outside the IIS - placing it in .VBS file, and running from command line through CScript, following QuickOPC COM programming examples (C:\Program Files (x86)\OPC Labs OPC Studio 2024.1\Examples-COM\VBScript\WSH\DocExamples\DataAccess\_EasyDAClient\ReadMultipleItems.DeviceSource.vbs) as template (see copy of revised "ReadMultipleItems.DeviceSource.vbs" example file below) appears QuickOPC OPC DA object call thru console is returning the correct "ADMIN" value as expected (see screenshot below)
Rem $Header: $
Rem Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved.
Rem#region Example
Rem This example shows how to read 4 items from the device, and display their values, timestamps and qualities.
Rem
Rem Find all latest examples here : opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Option Explicit
' Selects the data source for OPC reads (from device, from OPC cache, or dynamically determined).
' The data source (memory, OPC cache or OPC device) selection will be based on the desired value age and current status of
' data received from the server.
Const DADataSource_ByValueAge = 0
' OPC reads will be fulfilled from the cache in the OPC server.
Const DADataSource_Cache = 1
' OPC reads will be fulfilled from the device by the OPC server.
Const DADataSource_Device = 2
Dim ReadItemArguments1: Set ReadItemArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments1.ServerDescriptor.ServerClass = "DeltaV.DVSYSsvr.1"
ReadItemArguments1.ItemDescriptor.ItemID = "THISUSER/USERNAME.A_CV"
ReadItemArguments1.ReadParameters.DataSource = DADataSource_Device ' read will be from device
'Dim ReadItemArguments2: Set ReadItemArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
'ReadItemArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
'ReadItemArguments2.ItemDescriptor.ItemID = "Trends.Ramp (1 min)"
'ReadItemArguments2.ReadParameters.DataSource = DADataSource_Device ' read will be from device
'Dim ReadItemArguments3: Set ReadItemArguments3 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
'ReadItemArguments3.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
'ReadItemArguments3.ItemDescriptor.ItemID = "Trends.Sine (1 min)"
'ReadItemArguments3.ReadParameters.DataSource = DADataSource_Device ' read will be from device
'Dim ReadItemArguments4: Set ReadItemArguments4 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
'ReadItemArguments4.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
'ReadItemArguments4.ItemDescriptor.ItemID = "Simulation.Register_I4"
'ReadItemArguments4.ReadParameters.DataSource = DADataSource_Device ' read will be from device
Dim arguments(0)
Set arguments(0) = ReadItemArguments1
'Set arguments(1) = ReadItemArguments2
'Set arguments(2) = ReadItemArguments3
'Set arguments(3) = ReadItemArguments4
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
Dim results: results = Client.ReadMultipleItems(arguments)
Dim i: For i = LBound(results) To UBound(results)
Dim VtqResult: Set VtqResult = results(i)
If VtqResult.Succeeded Then
WScript.Echo "results(" & i & ").Vtq.ToString(): " & VtqResult.Vtq.ToString()
Else
WScript.Echo "results(" & i & ") *** Failure: " & VtqResult.ErrorMessageBrief
End If
Next
Rem#endregion Example
Attachments:
Please Log in or Create an account to join the conversation.
and thank you.
The COM demo application is essentially using the same method call as you were originally. That's why it is weird that the code in ASP behaves differently. The C++ source of the demo app is installed with QuickOPC, if you like to view it.
However, the code inside QuickOPC makes internal decisions about which methods to use, and it does not report back which method it has chosen. The decisions depends largely on availability: If the server does not support certain flavor of OPC DA 1/2/3, of course we choose something that server does support. But in your tests, the server was always the same server, so this should not make a difference. There are other factors: For example, the async operation require more involved security settings than the sync operations (because not only the client calls to the server, but also the client calls into the server). So it can happen that the sync interfaces work, but the async ones don't. I actually suspect that this may be the case here, because the ASP/IIS is quite restricted.
Now back to your test: Unfortunately the code you have used is incorrect, which explains why it always fails with the RPC error. This is partly my fault - I should have instructed you better. What happens here is that in COM API of QuickOPC, there are no method overloads, and you cannot just call ReadItemValue and pass it the "data source", as in .NET. For scenarios where more than the standard parameters need to be specified, you need to switch over to the ReadMultipleItemValues (albeit for just one item), and pass it an argument object that contains the full set of parameters.
So, you need to start with an example like this one: opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Late...20Read%20multiple%20items.html , reduce it to one item, and in the DAReadItemArguments object that gets passed to the ReadMultipleItems, set .ReadParameters.DataSource accordingly.
Also, after you do this and get it working, please test the same VBScript (with just modified output code) outside the IIS - placing it in .VBS file, and running from command line through CScript. The aim is to test whether the behavior depends on the hosting (ASP versus console).
Regards
Please Log in or Create an account to join the conversation.
- Kyle.Oshima@caltrol.com
- Topic Author
- Offline
- Platinum Member
- Posts: 35
- Thank you received: 1
<!--$$Header: $-->
<!-- Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. -->
<!---->
<!--Find all latest examples here : opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .-->
<%@ LANGUAGE="VBSCRIPT" %>
<html><head><t-itle>ReadAndDisplayValue_VBScript.asp</title></head>
<body>
<%
' Create EasyOPC-DA component
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
' Read item value and display it
' Note: An exception can be thrown from the statement below in case of failure. See other examples for proper error
' handling practices!
<!-- Response.Write Client.ReadItemValue("", "OPCLabs.KitServer", "Demo.Single")-->
On Error Resume Next
Client.InstanceParameters.Mode.AllowAsynchronousMethod = false
Response.Write "OPC Data Access - Read an item synchronously" & "<br>" & "<br>"
Dim Vtq: Set Vtq = Client.ReadItem("", "DeltaV.DVSYSsvr.1", "THISUSER/USERNAME.A_CV")
If Err.Number <> 0 Then
Response.Write "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0
Response.Write "Vtq: " & Vtq
%>
</body>
</html>
re: try to use read from Device, re-revising "ReadAndDisplayValue_VBScript.asp" example file adding DADataSource enumeration as defined in OPC Studio User's Guide and Reference DataSource Property (DAReadParameters) (see code below) all three enumeration values 0, 1, and 2 returns RPC server error (see screenshot below) -- note other force sync read example run from same IIS server to same target OPC DA server returns no such RPC error.
<!--$$Header: $-->
<!-- Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. -->
<!---->
<!--Find all latest examples here : opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .-->
<%@ LANGUAGE="VBSCRIPT" %>
<html><head><t-itle>ReadAndDisplayValue_VBScript.asp</title></head>
<body>
<%
' Create EasyOPC-DA component
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
' Read item value and display it
' Note: An exception can be thrown from the statement below in case of failure. See other examples for proper error
' handling practices!
<!-- Response.Write Client.ReadItemValue("", "OPCLabs.KitServer", "Demo.Single")-->
On Error Resume Next
Response.Write "OPC Data Access - Read a single item from the device" & "<br>" & "<br>"
<!--from www.opclabs.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/Us...adParameters~DataSource.html-->
' Selects the data source for OPC reads (from device, from OPC cache, or dynamically determined).
' The data source (memory, OPC cache or OPC device) selection will be based on the desired value age and current status of
' data received from the server.
'Const DADataSource_ByValueAge = 0
' OPC reads will be fulfilled from the cache in the OPC server.
'Const DADataSource_Cache = 1
' OPC reads will be fulfilled from the device by the OPC server.
'Const DADataSource_Device = 2
Dim Vtq: Set Vtq = Client.ReadItem("DeltaV.DVSYSsvr.1", "THISUSER/USERNAME.A_CV", 2)
If Err.Number <> 0 Then
Response.Write "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0
Response.Write "Vtq: " & Vtq
%>
</body>
</html>
As you indicate there are "many" ways to make read in OPC DA, what specific method is used in the noted QuickOPC demo from default product install (C:\Program Files (x86)\OPC Labs OPC Studio 2024.1\Demos-COM\EasyOPCDADemo.exe)? as that tool appears to return the correct "ADMIN" value as expected much like the vendor's internal as well as third-party Matrikon OPC DA client tools seemingly not encountering the supposed OPC server bug noted.
Attachments:
Please Log in or Create an account to join the conversation.
First of all, it not correct to say that the the script is not returning a value. That would be akin to getting back e.g. a null reference.
From the output of your script, however, it is clear a String-typed value is returned - and it is an empty string.
Second, with almost certainty, this is a server problem. This statement is not invalidated by the fact that other clients get a different value. Let me explain my reasons for this claim:
- QuickOPC code has been intentionally written to treat the Value-timestamp-quality triple received from the server as "sacred". That is, (aside from necessary type conversions) it never modifies its individual elements. So, if there is *some* Vtq received form the server, we always pass it to your code in the shape it was received.
- Of theory there can always be a bug in the above approach somewhere. Leaving aside the fact that it would be relatively difficult to actually create such bug, there is this: The code for all of this has its origins that are 20+ years old. It is time proven and it works well. Over the years, we dealt with many QuickOPC bugs - but there was not a single case in which the Vtq presented to your code was different from what the server has provided.
- Moreover, we have seen various server bugs that can cause this. This is compounded by the fact that there are *many* ways to make a Read in OPC-DA. The way the things are done differ between OPC DA 1.0, 2.x and 3.x. There are internally sync and async reads. And there is a read from the device and a read from the cache. In many cases the chosen way to do things is up to the client, and one client may be unlucky and chose the way that has a bug in the server.
- One relatively common bug in the servers (I am not saying it must be this one) is that if a Read is made immediately after OPCGroup object is created and an OPCItem added to it, the value is not immediately correct - only after certain time. Anyone who tests the server with the usual UI-based tools will inevitable introduce delays in order of seconds between these calls. And things will work for him well. But then the automated client will perform the calls one after another, and the server will show the bug.
What can be done?
- try to use read from Device: opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Late...tem%20from%20the%20device.html
- try to force Sync read: opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Late...an%20item%20synchronously.html
Also, OPCAnalyzer tool can be put in the middle between the client and the server and we can capture the "good" and "bad" communication and determine who is at fault. However, the tool has its own problems (such as that it only supports some specs), and doing these things always introduces a variant of the Heisenberg's indeterminacy principle: Thew behavior may change when the tool is used.
Regards
Please Log in or Create an account to join the conversation.
- Kyle.Oshima@caltrol.com
- Topic Author
- Offline
- Platinum Member
- Posts: 35
- Thank you received: 1
Using QuickOPC demos from default product install (C:\Program Files (x86)\OPC Labs OPC Studio 2024.1\Demos-COM\EasyOPCDADemo.exe) we have been able to demonstrate the product appears capable of successfully communicating with the DCS OPC DA server and reading values as needed matching vendor's internal as well as third-party Matrikon OPC DA client tools (see screenshots below)
However, following QuickOPC COM programming examples (C:\Program Files (x86)\OPC Labs OPC Studio 2024.1\Examples-COM\VBScript\ASP\ReadAndDisplayValue_VBScript.asp and Examples - OPC Data Access - Read a single item ) as template (see copy of revised "ReadAndDisplayValue_VBScript.asp" example file below) appears QuickOPC OPC DA object call is returning timestamp and quality but not value (see screenshot below)
<!--$$Header: $-->
<!-- Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. -->
<!---->
<!--Find all latest examples here : opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .-->
<%@ LANGUAGE="VBSCRIPT" %>
<html><head><t-itle>ReadAndDisplayValue_VBScript.asp</title></head>
<body>
<%
' Create EasyOPC-DA component
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
' Read item value and display it
' Note: An exception can be thrown from the statement below in case of failure. See other examples for proper error
' handling practices!
<!-- Response.Write Client.ReadItemValue("", "OPCLabs.KitServer", "Demo.Single")-->
On Error Resume Next
Dim Vtq: Set Vtq = Client.ReadItem("", "DeltaV.DVSYSsvr.1", "THISUSER/USERNAME.A_CV")
If Err.Number <> 0 Then
Response.Write "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0
Response.Write "Vtq: " & Vtq
%>
</body>
</html>
Attachments:
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-Classic in COM
- Reading, Writing, Subscriptions, Property Access
- QuickOPC VBScript ASP example script not returning value