[python-win32] problem accessing OPC clients from thread

Graham Bloice graham.bloice at trihedral.com
Mon Dec 3 11:21:35 CET 2007


Jeff Peery wrote:
> Hello,
> I'm getting in a bit over my head here and need some help. I'm running
> a simple wxpython application that runs a thread in the background.
> The thread is supposed to read and write data to/from an OPC server -
> which I use to communicate to a PLC (programmable logic controller,
> for process automation). My OPC module works well for just reading and
> writing to the OPC server; however when I try to read and write to the
> OPC server from within the thread it doesn't work. I get this error:
>  
> Here's the snippet from my thread:
> # connect to server 
> opcServerName = 'the server name goes here'
> opcItemName = 'the opc item goes here'
> (server, group) = myOPC.connectServer(opcServerName)
> item = myOPC.addItem(opcItemName, group)
> value = myOPC.readItemValue(item)
> # the value return a tuple of info including a value and timestamp and
> quality
> Here's the error that's returned:
> line 124, in readItemValue
>     return opcItem.Read(0x1)
>   File "<COMObject AddItem>", line 3, in Read
>   File "C:\Python25\lib\site-packages\win32com\client\dynamic.py",
> line 258, in _ApplyTypes_
>     result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags,
> retType, argTypes) + args)
> com_error: (-2147352567, 'Exception occurred.', (0, None, None, None,
> 0, -2147221008), None)
The error code indicated (-2147221008) or 0x800401F0, is "CoInitialize
has not been called".  I would guess that you haven't done that on your
thread.  Try adding a pythoncom.CoInitialize() or CoInitializeEx(0 call
to the start of the thread.  You might need the Ex version to set the
correct threading model.
>  
> I attached my OPC module, if its important to include the wxapp I can
> do that to, but it's pretty apparent that the problem only happens
> when I call my OPC funcitons from within a thread...
>  
> I suppose its also worthwhile to mention that I need to access the OPC
> module from within a thread (thats not the main applications thread)
> because I'm trying to aquire data from a PLC and I want to do that
> continuously and not lock up my program.
>  
> Any ideas on how I might get this thing to work within the thread? Thanks!
>  
Although I think your code will work, it's not using OPC in it's normal
event driven mode of operation where the OPC Server will send an event
when the data read from the PLC changes.  You are using a polling mode,
via ReadItemValue().  If you added an event handler for the DataChange
event of the group then you would be automatically informed of any data
(or quality) changes without the need for a polling thread.  One caveat
of this is that you need to have a unique client handle for each data
item in the group and the supplied code always seems to just use a
constant '1' in the call to OPCItems.AddItem(). (in addItem()).

-- 
Regards,

Graham Bloice



More information about the python-win32 mailing list