Jump to content

Opc Com/ole Problem Still


Recommended Posts

So a while ago I wrote here asking for help with a problem I am having with a couple of dll used for automation. These dlls are part of the open standard called OPC. I have no problems making com calls to any of the interface except for the last one in the tree.

Data Access Auto dll

OPC Server ..... Good All Methods and Properties are accessable

OPC Groups ..... Good All Methods and Properties are accessable

OPC Group ..... Good All Methods and Properties are accessable

OPC Items ..... Good All Methods and Properties are accessable

OPC Item ..... I can get the container but when access interfaces it tells me they don't exist

Historical Data Access dll

HDA Sever ... Good

HDA Items .... Good

HDA Item .... Can get the container and but again methods and properties are none existant

I have reviewd both with OLE Viewer and have rewrote this in VBA to prove the dlls work. These same dlls I can use with perl but want AutoIT support for more testing capabilities.

ANY HELP

I can provide code dlls help files all of which is open to the public to view

PLEASE PLEASE PLEASE Little Help?

Link to comment
Share on other sites

Well to start, I would attach your DLL and your autoit source with your attempt at calling them.

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

Well to start, I would attach your DLL and your autoit source with your attempt at calling them.

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Install a custom error handler

$strServerName = ("Matrikon.OPC.DesktopHistorian.1")

$oHDA=ObjCreate("Matrikon.OPCHDA.Automation.1")

$testID=$oHDA.Connect($strServerName,"localhost")

$ServerName = $oHDA.ServerName

MsgBox(4096,"Connected to ...",$ServerName)

$OPCItems = $oHDA.OPCHDAItems

;$OPCBrowser = $oHDA.CreateBrowser()

; $OPCItem1=$OPCBrowser->GetItemID('Random.Int1');

$OPCItems.AddItem('Random.Int1',0)

$OPCItem1=$OPCItems.Item('Random.Int1')

$Count=$OPCItems.Count

MsgBox(4096,"OPCItem1",$OPCItem1)

MsgBox(4096,"Item Count",$Count)

$NumItems = 1

For $OPCItem In $OPCItems

$ServerHandles=$OPCItem.ServerHandle

;MsgBox(4096,"OBJName",ObjName($OPCItem))

MsgBox(4096,"Handle",$ServerHandles)

Next

$ItemID=$OPCItem1.ItemID

$ClientHandle =$OPCItem1.ClientHandle

MsgBox(4096,"Test",$ServerHandles)

$OPCItem1=$OPCItems.GetOPCHDAItem($ServerHandles)

$ServerHandles=$OPCItem1.ServerHandle

MsgBox(4096,"Test",$ServerHandles)

$ClientHandle =$OPCItem1.ClientHandle

MsgBox(4096,"Test",$ClientHandle)

$TimeStamp="04/24/2006 14:22:33.000"

$Values=100

$Qualities=262336

MsgBox(4096,"OBJName",ObjName($OPCItem1))

;$OPCItem1.Update($TimeStamp,$Values,$Qualities)

;$OPCItems.SyncInsert($NumItems,$ServerHandles,"04/24/2006 14:22:33.000",$Values,$Qualities)

; This is my custom error handler

Func MyErrFunc()

$HexNumber=hex($oMyError.number,8)

Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _

"Number is: " & $HexNumber & @CRLF & _

"Windescription is: " & $oMyError.windescription )

SetError(1) ; something to check for when this function returns

Endfunc

Link to comment
Share on other sites

So a while ago I wrote here asking for help with a problem I am having with a couple of dll used for automation. These dlls are part of the open standard called OPC. I have no problems making com calls to any of the interface except for the last one in the tree.

Data Access Auto dll

OPC Server ..... Good All Methods and Properties are accessable

OPC Groups ..... Good All Methods and Properties are accessable

OPC Group ..... Good All Methods and Properties are accessable

OPC Items ..... Good All Methods and Properties are accessable

OPC Item ..... I can get the container but when access interfaces it tells me they don't exist

Historical Data Access dll

HDA Sever ... Good

HDA Items .... Good

HDA Item .... Can get the container and but again methods and properties are none existant

I have reviewd both with OLE Viewer and have rewrote this in VBA to prove the dlls work. These same dlls I can use with perl but want AutoIT support for more testing capabilities.

ANY HELP

I can provide code dlls help files all of which is open to the public to view

PLEASE PLEASE PLEASE Little Help?

Link to comment
Share on other sites

Just a note to all who have an interest in technology. OPC is an open standard that gets data from any device.

If the deevice provides data in any format OPC handles it.

A guy took a MODBUS device and connected his house to it. Now all the lights power etc in house including his security system were connected and he could control his whole house.

Production plants, Oil refineries etc all use OPC.

OPC IS REALLY GREAT STUFF

Link to comment
Share on other sites

www.opcfoundation.com

On this website is all the docs and info about OPC and the specs aswell as the documents for the dlls.

PLEASE ANYONE. I know that AutoIT should be able to do this.

If it can then there are so many things that we can add to it.

I already have created several remote monitor systems as well as a testing framework for autoit.

It would be a real shame if I had to drop AutoIT and reauthor everything in perl

:think:

Link to comment
Share on other sites

[Option Compare Database

Option Explicit

Option Base 1

Const MaxItemCount = 100

Dim WithEvents OPCMyserver As OPCServer

Dim WithEvents OPCMygroups As OPCGroups

Dim WithEvents OPCMygroup As OPCGroup

Dim OPCMyitems As OPCItems

Dim OPCMyitem As OPCItem

Dim ItemCount As Integer

Private Sub Class_Terminate()

Dim Errors() As Long

On Error Resume Next

OPCMygroup.IsActive = False

OPCMygroups.Remove OPCMygroup.ServerHandle

Set OPCMyitems = Nothing

Set OPCMyitem = Nothing

Set OPCMygroups = Nothing

Set OPCMygroup = Nothing

OPCMyserver.Disconnect

Set OPCMyserver = Nothing

End Sub

Function Connect(ServerName As String)

On Error GoTo ConnectError

Set OPCMyserver = New OPCServer

OPCMyserver.Connect ServerName, ""

Connect = True

Exit Function

ConnectError:

Connect = False

End Function

Function AddGroup(Optional OPCGroupsName As String, Optional Active As Boolean, Optional UpdateRate As Long, Optional CallBack As Long) As Variant

On Error GoTo AddError

Set OPCMygroups = OPCMyserver.OPCGroups

If Not OPCGroupsName = "" Then

Set OPCMygroup = OPCMygroups.Add(OPCGroupsName)

Else

Set OPCMygroup = OPCMygroups.Add

End If

If Not Active = "" Then

If Active = True Then

OPCMygroup.IsActive = True

Else

OPCMygroup.IsActive = False

End If

End If

If Not UpdateRate = "" Then

OPCMygroup.UpdateRate = UpdateRate

End If

If Not CallBack = "" Then

Select Case CallBack

Case -1

'No CallBack

Case 0

'AutoDetect

Case 1

'Advise 1.0a

Case 2

'Connection Points 2.0

End Select

End If

AddGroup = OPCMygroup.ClientHandle

Exit Function

AddError:

AddGroup = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetClientHandle(GroupName As String)

Dim tHandle As Long

tHandle = OPCMygroup.ClientHandle

GetClientHandle = tHandle

End Function

Sub Advise(bAdvise As Boolean)

On Error Resume Next

OPCMygroup.IsActive = bAdvise

OPCMygroup.IsSubscribed = bAdvise

If bAdvise = True Then

Dim anItem As OPCItem

For Each anItem In OPCMygroup.OPCItems

anItem.Read OPCCache ', value, qual, time ' If subscribed, don't do this!

''Cells(anItem.ClientHandle, 2) = anItem.Value

'Cells(anItem.ClientHandle, 3) = anItem.TimeStamp

' Cells(anItem.ClientHandle, 3) = DateAdd("h", 9, anItem.TimeStamp)

'Cells(anItem.ClientHandle, 4) = anItem.Quality

Set anItem = Nothing

Next anItem

End If

End Sub

Sub UnAdvise()

OPCMygroup.IsSubscribed = False

End Sub

Sub SyncWrite()

On Error Resume Next

Dim anItem As OPCItem

For Each anItem In OPCMygroup.OPCItems

'anItem.Write Cells(anItem.ClientHandle, 2)

Set anItem = Nothing

Next anItem

End Sub

Private Sub OPCMygroup_DataChange(ByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles() As Long, ItemValues() As Variant, Qualities() As Long, TimeStamps() As Date)

Dim i As Integer

For i = 1 To NumItems

'Cells(ClientHandles(i), 2) = ItemValues(i)

'Cells(ClientHandles(i), 3) = TimeStamps(i)

' Cells(ClientHandles(i), 3) = DateAdd("h", 9, TimeStamps(i))

'Cells(ClientHandles(i), 4) = Qualities(i)

Next i

End Sub

Private Sub OPCMyserver_ServerShutDown(ByVal Reason As String)

MsgBox "Server shutdown"

End Sub

Function GetStartTime() As Date

GetStartTime = OPCMyserver.StartTime

End Function

Function GetCurrentTime() As Date

GetCurrentTime = OPCMyserver.CurrentTime

End Function

Function GetLastUpdateTime() As Date

GetLastUpdateTime = OPCMyserver.LastUpdateTime

End Function

Function GetMajorVersion() As Integer

GetMajorVersion = OPCMyserver.MajorVersion

End Function

Function GetMinorVersion() As Integer

GetMinorVersion = OPCMyserver.MinorVersion

End Function

Function GetBuildNumber() As Integer

GetBuildNumber = OPCMyserver.BuildNumber

End Function

Function GetVendorInfo() As String

GetVendorInfo = OPCMyserver.VendorInfo

End Function

Function GetServerState() As Long

GetServerState = OPCMyserver.ServerState

End Function

Function GetBandwidth() As Long

GetBandwidth = OPCMyserver.Bandwidth

End Function

Function GetClientName() As String

GetClientName = OPCMyserver.ClientName

End Function

Function GetOPCGroups() As OPCGroups

Set GetOPCGroups = OPCMyserver.OPCGroups

End Function

Function GetPublicGroupNames() As Variant

GetPublicGroupNames = OPCMyserver.PublicGroupNames

End Function

Function GetLocaleID() As Long

GetLocaleID = OPCMyserver.LocaleID

End Function

Function GetServerName() As String

GetServerName = OPCMyserver.ServerName

End Function

Function AddItem(lClientHandle As Long, strItemID As String, Optional AccessPath As String) As Long

On Error GoTo Error

Dim TEMP As OPCItem

Set TEMP = OPCMyitems.AddItem(strItemID, lClientHandle)

AddItem = TEMP.ItemID

Error:

AddItem = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetItemValue(ServerHandle As Long) As Variant

Dim AnOPCItem As OPCItem

Dim Value As Variant

Dim strTemp As String

Set AnOPCItem = OPCMyitems.GetOPCItem(ServerHandle)

AnOPCItem.Read OPCCache

Value = AnOPCItem.Value

If IsArray(Value) Then

'strTemp = StrConv(Value, vbUnicode)

GetItemValue = "Array?"

Else

GetItemValue = Value

End If

End Function

Function GetItemQuality(ServerHandle As Long) As Long

Dim AnOPCItem As OPCItem

Set AnOPCItem = OPCMyitems.GetOPCItem(ServerHandle)

AnOPCItem.Read OPCCache

GetItemQuality = AnOPCItem.Quality

End Function

Function GetItemTimeStamp(ServerHandle As Long) As Date

Dim AnOPCItem As OPCItem

Set AnOPCItem = OPCMyitems.GetOPCItem(ServerHandle)

AnOPCItem.Read OPCCache

GetItemTimeStamp = AnOPCItem.TimeStamp

End Function

Function GetItemID(ServerHandle As Long) As String

Dim AnOPCItem As OPCItem

Set AnOPCItem = OPCMyitems.GetOPCItem(ServerHandle)

AnOPCItem.Read OPCCache

GetItemID = AnOPCItem.ItemID

End Function

Function GetDefaultGroupIsActive() As Variant

On Error GoTo Error

GetDefaultGroupIsActive = OPCMygroups.DefaultGroupIsActive

Exit Function

Error:

GetDefaultGroupIsActive = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetDefaultGroupUpdateRate() As Variant

On Error GoTo Error

GetDefaultGroupUpdateRate = OPCMygroups.DefaultGroupUpdateRate()

Exit Function

Error:

GetDefaultGroupUpdateRate = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetDefaultGroupDeadBand() As Variant

On Error GoTo Error

GetDefaultGroupDeadBand = OPCMygroups.DefaultGroupDeadband

Exit Function

Error:

GetDefaultGroupDeadBand = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetDefaultGroupLocaleID() As Variant

On Error GoTo Error

GetDefaultGroupLocaleID = OPCMygroups.DefaultGroupLocaleID

Exit Function

Error:

GetDefaultGroupLocaleID = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetDefaultGroupTimeBias() As Variant

On Error GoTo Error

GetDefaultGroupTimeBias = OPCMygroups.DefaultGroupTimeBias

Exit Function

Error:

GetDefaultGroupTimeBias = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupsCount() As Variant

On Error GoTo Error

GetGroupsCount = OPCMygroups.Count

Exit Function

Error:

GetGroupsCount = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupName(Key As Integer) As String

On Error GoTo Error

Set OPCMygroup = OPCMygroups.Item(Key)

GetGroupName = OPCMygroup.Name

Exit Function

Error:

GetGroupName = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupIsPublic(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupIsPublic = OPCMygroup.IsPublic

Exit Function

Error:

GetGroupIsPublic = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupIsActive(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupIsActive = OPCMygroup.IsActive

Exit Function

Error:

GetGroupIsActive = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupIsSubscribed(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupIsSubscribed = OPCMygroup.IsSubscribed

Exit Function

Error:

GetGroupIsSubscribed = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupClientHandle(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupClientHandle = OPCMygroup.ClientHandle

Exit Function

Error:

GetGroupClientHandle = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupServerHandle(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupServerHandle = OPCMygroup.ServerHandle

Exit Function

Error:

GetGroupServerHandle = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupLocaleID(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupLocaleID = OPCMygroup.LocaleID

Exit Function

Error:

GetGroupLocaleID = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupTimeBias(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupTimeBias = OPCMygroup.LocaleID

Exit Function

Error:

GetGroupTimeBias = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupDeadBand(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupDeadBand = OPCMygroup.DeadBand

Exit Function

Error:

GetGroupDeadBand = Hex$(Err.Number) & " " & Err.Description

End Function

Function GetGroupUpdateRate(GroupName As String) As Variant

On Error GoTo Error

Set OPCMygroup = OPCMygroups.GetOPCGroup(GroupName)

GetGroupUpdateRate = OPCMygroup.UpdateRate

Exit Function

Error:

GetGroupUpdateRate = Hex$(Err.Number) & " " & Err.Description

End Function

Function RemoveGroup(GroupName As Variant) As Variant

On Error GoTo Error

OPCMygroups.Remove (GroupName)

RemoveGroup = "Group " & GroupName & " was removed."

Exit Function

Error:

RemoveGroup = Hex$(Err.Number) & " " & Err.Description

End Function

Function RemoveAllGroups() As Variant

On Error GoTo Error

OPCMygroups.RemoveAll

RemoveAllGroups = "All Groups were removed."

Exit Function

Error:

RemoveAllGroups = Hex$(Err.Number) & " " & Err.Description

End Function

Sub ActivateItem(ItemID As Long, Activate As Boolean)

Dim AnOPCItem As OPCItem

Set AnOPCItem = OPCMyitems.GetOPCItem(ItemID)

AnOPCItem.IsActive = Activate

End Sub

Link to comment
Share on other sites

I have discussed this know with several oof our developers here and it does seem like the flaw maybe in the way AutoIT handles object ...... This is what they believe anyways. We have lots of scripts written in vba that work fine.

Has anyone had any luck? Just give a shout out if you're workin on some ideas.

Thanx

Link to comment
Share on other sites

I have discussed this know with several oof our developers here and it does seem like the flaw maybe in the way AutoIT handles object ...... This is what they believe anyways. We have lots of scripts written in vba that work fine.

Has anyone had any luck? Just give a shout out if you're workin on some ideas.

Thanx

Be patient our main Dev SvenP as very little time to give you some support but I warn him on the subject.

You will get an answer.

:think:

Link to comment
Share on other sites

Hello CrashOverRideZX,

I was trying to run your AutoIt sample code, but I guess I am missing a DLL.

The code stops at the line $oHDA.Connect(), stating that it can't find the object with AppID: Matrikon.OPC.DesktopHistorian.1

On www.opcfoundation.com a usercode/password is required to download the software. Could you provide me the missing files?

On what line of your sample script did you get the error? What was the exact description of that error?

The file opchdaauto.dll seems to be allright for AutoIt: All interfaces are inherited from Idispatch and all properties/methods are defined in the type library. Could be something in AutoIt, but I can't test it.

Regards,

-Sven

Link to comment
Share on other sites

Fantastic thanx Sven for replying.

I will make this somewhat easier for you.

The Matrikon.OPC.DesktopHistorian.1 is the ProgID for an HDA Server. Unfortunatly I cannot provide this as it is licenced software but when we can do is get you the Simualtion server.

http://www.matrikonopc.com/portal/download...D=178&sd=y&ref=

This server supports DA and is open to the public.

Now in the next reply I will add the code test. The problem with this is that it cannot get the interfaces from the last collection Item.

Link to comment
Share on other sites

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Install a custom error handler

$strServerName = ("Matrikon.OPC.Simualtion.1")

$oDA=ObjCreate("OPC.Automation.1")

$Output = ""

Dim $arItems[4]

$arItems[0]="Random.Int1"

$arItems[1]="Random.Int2"

$arItems[2]="Random.Int4"

$arItems[3]="Random.String"

;Begin Testing of the Server Object Methods

;GetOPCSERVERS

$OPCServers = $oDA.GetOPCServers

For $OPCServer IN $OPCServers

$Output = $Output & @CRLF & $OPCServer

NEXT

MsgBox(4096,"Test",$Output)

$testID=$oDA.Connect($strServerName,"localhost")

MsgBox(4096,"Test",$testID)

;Begin Testing of the Server Object Properties

$Output = $oDA.ServerName

MsgBox(4096,"Test",$Output)

$Output = $oDA.StartTime & @CRLF & $oDA.CurrentTime & @CRLF & $oDA.LastUpdateTime

MsgBox(4096,"Test",$Output)

$Output = $oDA.MajorVersion & @CRLF & $oDA.MinorVersion & @CRLF & $oDA.BuildNumber

MsgBox(4096,"Test",$Output)

$Output = $oDA.VendorInfo & @CRLF & $oDA.ServerState & @CRLF & $oDA.LocaleID

MsgBox(4096,"Test",$Output)

$Output = $oDA.Bandwidth & @CRLF & $oDA.ServerNode & @CRLF & $oDA.ClientName

MsgBox(4096,"Test",$Output)

$OPCGroups = $oDA.OPCGroups

$GroupsDebug=0

$OPCGroup1=$OPCGroups.Add("Test1")

If ($GroupsDebug=1) Then

MsgBox(4096,"Test Debug","Groups Parent...." & $OPCGroups.Parent)

MsgBox(4096,"Test Debug","Groups DefaultGroupIsActive...." & $OPCGroups.DefaultGroupIsActive)

MsgBox(4096,"Test Debug","Groups DefaultGroupUpdateRate...." & $OPCGroups.DefaultGroupUpdateRate)

MsgBox(4096,"Test Debug","Groups DefaultGroupDeadBand...." & $OPCGroups.DefaultGroupDeadBand)

MsgBox(4096,"Test Debug","Groups DefaultGroupLocaleID...." & $OPCGroups.DefaultGroupLocaleID)

MsgBox(4096,"Test Debug","Groups DefaultGroupTimeBias...." & $OPCGroups.DefaultGroupTimeBias)

MsgBox(4096,"Test Debug","Groups Count...." & $OPCGroups.Count)

$OPCGroup2=$OPCGroups.Add("Test2")

$OPCGroup3=$OPCGroups.Add("Test3")

$OPCGroup4=$OPCGroups.Add("Test4")

MsgBox(4096,"Test Debug","Groups Parent...." & $OPCGroups.Parent)

MsgBox(4096,"Test Debug","Groups DefaultGroupIsActive...." & $OPCGroups.DefaultGroupIsActive)

MsgBox(4096,"Test Debug","Groups DefaultGroupUpdateRate...." & $OPCGroups.DefaultGroupUpdateRate)

MsgBox(4096,"Test Debug","Groups DefaultGroupDeadBand...." & $OPCGroups.DefaultGroupDeadBand)

MsgBox(4096,"Test Debug","Groups DefaultGroupLocaleID...." & $OPCGroups.DefaultGroupLocaleID)

MsgBox(4096,"Test Debug","Groups DefaultGroupTimeBias...." & $OPCGroups.DefaultGroupTimeBias)

MsgBox(4096,"Test Debug","Groups Count...." & $OPCGroups.Count)

EndIf

$GroupDebug=0

If ($GroupDebug=1) Then

FOR $OPCGroup IN $OPCGroups ; Here it starts..

MsgBox(4096,"Test Debug","Group Active...." & $OPCGroup.IsActive)

MsgBox(4096,"Test Debug","Group Name...." & $OPCGroup.Name)

MsgBox(4096,"Test Debug","Group Parent...." & $OPCGroup.Parent)

;MsgBox(4096,"Test Debug","Group IsPublic...." & $OPCGroup.IsPublic)

MsgBox(4096,"Test Debug","Group IsSubscribed...." & $OPCGroup.IsSubscribed)

MsgBox(4096,"Test Debug","Group ClientHandle...." & $OPCGroup.ClientHandle)

MsgBox(4096,"Test Debug","Group ServerHandle...." & $OPCGroup.ServerHandle)

MsgBox(4096,"Test Debug","Group LocaleID...." & $OPCGroup.LocaleID)

MsgBox(4096,"Test Debug","Group TimeBias...." & $OPCGroup.TimeBias)

MsgBox(4096,"Test Debug","Group DeadBand...." & $OPCGroup.DeadBand)

MsgBox(4096,"Test Debug","Group UpdateRate...." & $OPCGroup.UpdateRate)

NEXT

EndIF

$OPCGroup1ID=$OPCGroup1.ClientHandle

$OPCItems=$OPCGroup1.OPCItems

Dim $arError[4]

$ItemsDebug=1

IF ($ItemsDebug=1) Then

MsgBox(4096,"Test Debug","Items Parent...." & $OPCItems.Parent)

MsgBox(4096,"Test Debug","Items DefaultRequestedDataType...." & $OPCItems.DefaultRequestedDataType)

MsgBox(4096,"Test Debug","Items DefaultAccessPath...." & $OPCItems.DefaultAccessPath)

MsgBox(4096,"Test Debug","Items DefaultIsActive...." & $OPCItems.DefaultIsActive)

$OPCitems.DefaultIsActive=False

MsgBox(4096,"Test Debug","Items DefaultIsActive...." & $OPCItems.DefaultIsActive)

MsgBox(4096,"Test Debug","Items Count...." & $OPCItems.Count)

;$arError=$OPCItems.Validate(4,$arItems)

;$OPCItem1=$OPCItems.AddItem($arItems[0],$OPCGroup1ID)

;$OPCItem2=$OPCItems.AddItem($arItems[1],$OPCGroup1ID)

;$OPCItem3=$OPCItems.AddItem($arItems[2],$OPCGroup1ID)

;$OPCItem4=$OPCItems.AddItem($arItems[3],$OPCGroup1ID)

;MsgBox(4096,"Test Debug","Items Count...." & $OPCItems.Count)

EndIF

$OPCItem1=$OPCItems.AddItem($arItems[0],$OPCGroup1ID)

$OPCItem2=$OPCItems.AddItem($arItems[1],$OPCGroup1ID)

$OPCItem3=$OPCItems.AddItem($arItems[2],$OPCGroup1ID)

$OPCItem4=$OPCItems.AddItem($arItems[3],$OPCGroup1ID)

MsgBox(4096,"Test Debug","Items Count...." & $OPCItems.Count)

$aProps=ObjectGetProperties($OPCItem1)

for $Property in $aProps; Display each property in Editbox

MsgBox(4096,"Test Debug","OPCITEMS Property....." & $Property)

Next

;$OPCItem1HandleIS = $oDA.OPCGroups.OPCGroup.OPCItems.OPCItem.ClientHandle

;***********THIS IS WHERE PROBLEMS BEGIN****************!!!!!

$OPCItem1ClientHandle = $OPCItem1.ClientHandle

$OPCItem1ServerHandle = $OPCItem1.ServerHandle

a

MsgBox(4096,"Test Debug","OPCITEMS Property....." & $OPCItem1HandleIs)

;$OPCItem=$OPCItems.OPCItem

;MsgBox(4096,"Test Debug","Testing.,.." & $OPCItems.AccessPath)

$ItemDebug=0

If ($ItemDebug=1) Then

FOR $OPCItem IN $OPCItems

MsgBox(4096,"Test Debug","Item ..." & $OPCItem)

MsgBox(4096,"Test Debug","Item ClientHandle..." & $OPCItem.AccessPath)

NEXT

EndIF

Func ObjectGetProperties($oObj)

;DESCRIPTION: Retrieves the description of all writable properties of the given Object.

;REQUIRES: tlbinf32.dll (distributed with Visual Studio)

;PARAMETERS: $oApp - Pointer to an active object

;DATE: 2006-01-29

;AUTHOR: SvenP

;CREDITS: To Dale Holm

Dim $oTLA, $oTLI, $TLIMember, $aProperties[1]

Const $cINVOKE_FUNC=1

; A method (=function)

Const $cINVOKE_PROPERTYGET=2

; Read-only property

Const $cINVOKE_PROPERTYPUT=4

; Read/write property

Const $cINVOKE_PROPERTYPUTREF=8

; Reference property

if not IsObj($oObj) then Return

$oTLA = ObjCreate("TLI.TLIApplication")

; oTLA is a _TLIApplication interface

$oTLI = $oTLA.InterfaceInfoFromObject($oObj)

; oTLI is a InterfaceInfo interface

For $TLIMember in $oTLI.Members

; This interface contains both methods and properties

if $TLIMember.InvokeKind=$cINVOKE_PROPERTYPUT then

; Get only WRITABLE prperties

Redim $aProperties[uBound($aProperties)+1]

; We don't know the number of properties in advance

$aProperties[uBound($aProperties)-1]=$TLIMember.Name

; Add the name of the property to array.

EndIf

Next

return $aProperties

EndFunc

; This is my custom error handler

Func MyErrFunc()

$HexNumber=hex($oMyError.number,8)

Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _

"Number is: " & $HexNumber & @CRLF & _

"Windescription is: " & $oMyError.windescription )

SetError(1) ; something to check for when this function returns

Endfunc

Link to comment
Share on other sites

Hello CrashOverRideZX,

It took me some time to create a reliable testing environment. Your code relies on interaction with a lot of external objects/interfaces, so I had to be sure I use a clean system for debugging.

I have located the problem, but it's difficult to solve. The errors are caused by a safeguard I built in.

Because AutoIt is a autonomous scripting language (not embeddeded in the OS, like VBScript), I had to be sure that it is safe for the script to call external functions. One rule in AutoIt developing says: prevent Windows exceptions errors at all cost (we don't like sending automatic error reports to Mr. Microsoft).

In this case, when methods or properties of external objects are being called, I check every time if the interface being called supports the IDispatch type interface. If not, the script refuses to use it. Unlike VBScript, which does not make this check at all (In VB/VBA the code knows in advance which objects it's going to use, because it will be pre-compiled).

I have checked the automation interfaces derived from Matrikon.OPC.Automation and Matrikon.OPCHDA.Automation. They all support IDispatch properly, but I noticed a weird omission in the interfaces called OPCItem and OPCHDAItem. According to the type library, both are inherited from IDispatch, but they fail with error E_NOINTERFACE when I ask them to give me the IDispatch interface.

If I talk 'weirdo language', you can see a visualization of the problem in this screenshot of OleView:

I only know of two ways to solve this:

A. I disable the safeguard in AutoIt.

B. You ask MatrikonOPC to add support for QI IDispatch to these two interfaces.

I opt for solution B, because they did implement it properly for their other interfaces. Furthermore, I have never run into this specific problem with any other object. And I can assure you, I have tested many weird automation Objects in AutoIt.

-Sven

Link to comment
Share on other sites

Thanx alot Sven.

Well I guess my next question would be how to disable the safegaurd.

I am looking into adding the support to the dlls but we do have some concerns about doing so.....

And as I am the only one with the schedule for it I guess I must learn how to add the support.

But THANX ALOT FOR ALL WHO HELPED OUT WITH THIS

AUTOIT ROCKS

Link to comment
Share on other sites

CrashOverRideZX,

It has been fixed in AutoIt beta version 3.1.1.122, but I'm currenly not able to test it.

Please confirm if this version has solved your problem.

Regards,

-Sven

Link to comment
Share on other sites

  • 2 years later...

Hi Crash

I am trying too to connect to OPC but it does not work.

Could you help me a little?

The Connection to the OPC Server works (thaks to BugFix from the German Forum), but i cant get any Groups or Items...

Edited by Sayen
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...