20 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 import Pyro.core as pyro |
21 import Pyro.core as pyro |
22 from Pyro.errors import PyroError |
22 from Pyro.errors import PyroError |
23 import traceback |
23 import traceback |
24 from time import sleep |
24 from time import sleep |
|
25 import copy |
25 |
26 |
26 def PYRO_connector_factory(uri, pluginsroot): |
27 def PYRO_connector_factory(uri, pluginsroot): |
27 """ |
28 """ |
28 This returns the connector to Pyro style PLCobject |
29 This returns the connector to Pyro style PLCobject |
29 """ |
30 """ |
57 # Check connection is effective. |
58 # Check connection is effective. |
58 # lambda is for getattr of GetPLCstatus to happen inside catcher |
59 # lambda is for getattr of GetPLCstatus to happen inside catcher |
59 if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None: |
60 if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None: |
60 pluginsroot.logger.write_error("Cannot get PLC status - connection failed.\n") |
61 pluginsroot.logger.write_error("Cannot get PLC status - connection failed.\n") |
61 return None |
62 return None |
|
63 |
|
64 # for safe use in from debug thread, must create a copy |
|
65 RemotePLCObjectProxyCopy = copy.copy(RemotePLCObjectProxy) |
62 |
66 |
63 class PyroProxyProxy: |
67 class PyroProxyProxy: |
64 """ |
68 """ |
65 A proxy proxy class to handle Beremiz Pyro interface specific behavior. |
69 A proxy proxy class to handle Beremiz Pyro interface specific behavior. |
66 And to put pyro exception catcher in between caller and pyro proxy |
70 And to put pyro exception catcher in between caller and pyro proxy |
69 """ |
73 """ |
70 This func returns the real Pyro Proxy. |
74 This func returns the real Pyro Proxy. |
71 Use this if you musn't keep reference to it. |
75 Use this if you musn't keep reference to it. |
72 """ |
76 """ |
73 return RemotePLCObjectProxy |
77 return RemotePLCObjectProxy |
|
78 |
|
79 def _PyroStartPLC(self): |
|
80 """ |
|
81 pluginsroot._connector.GetPyroProxy() is used |
|
82 rather than RemotePLCObjectProxy because |
|
83 object is recreated meanwhile, |
|
84 so we must not keep ref to it here |
|
85 """ |
|
86 if pluginsroot._connector.GetPyroProxy().GetPLCstatus() == "Dirty": |
|
87 """ |
|
88 Some bad libs with static symbols may polute PLC |
|
89 ask runtime to suicide and come back again |
|
90 """ |
|
91 pluginsroot.logger.write("Force runtime reload\n") |
|
92 pluginsroot._connector.GetPyroProxy().ForceReload() |
|
93 pluginsroot._Disconnect() |
|
94 # let remote PLC time to resurect.(freeze app) |
|
95 sleep(0.5) |
|
96 pluginsroot._Connect() |
|
97 return pluginsroot._connector.GetPyroProxy().StartPLC() |
|
98 StartPLC = PyroCatcher(_PyroStartPLC, False) |
|
99 |
|
100 |
|
101 def _PyroGetTraceVariables(self): |
|
102 """ |
|
103 for safe use in from debug thread, must use the copy |
|
104 """ |
|
105 return RemotePLCObjectProxyCopy.GetTraceVariables() |
|
106 GetTraceVariables = PyroCatcher(_PyroGetTraceVariables) |
|
107 |
74 |
108 |
75 def __getattr__(self, attrName): |
109 def __getattr__(self, attrName): |
76 if not self.__dict__.has_key(attrName): |
110 member = self.__dict__.get(attrName, None) |
77 if attrName=="StartPLC": |
111 if member is None: |
78 def _StartPLC(): |
112 def my_local_func(*args,**kwargs): |
79 """ |
113 return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs) |
80 pluginsroot._connector.GetPyroProxy() is used |
114 member = PyroCatcher(my_local_func, None) |
81 rather than RemotePLCObjectProxy because |
|
82 object is recreated meanwhile, |
|
83 so we must not keep ref to it here |
|
84 """ |
|
85 if pluginsroot._connector.GetPyroProxy().GetPLCstatus() == "Dirty": |
|
86 """ |
|
87 Some bad libs with static symbols may polute PLC |
|
88 ask runtime to suicide and come back again |
|
89 """ |
|
90 pluginsroot.logger.write("Force runtime reload\n") |
|
91 pluginsroot._connector.GetPyroProxy().ForceReload() |
|
92 pluginsroot._Disconnect() |
|
93 # let remote PLC time to resurect.(freeze app) |
|
94 sleep(0.5) |
|
95 pluginsroot._Connect() |
|
96 return pluginsroot._connector.GetPyroProxy().StartPLC() |
|
97 member = PyroCatcher(_StartPLC, False) |
|
98 else: |
|
99 def my_local_func(*args,**kwargs): |
|
100 return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs) |
|
101 member = PyroCatcher(my_local_func, None) |
|
102 self.__dict__[attrName] = member |
115 self.__dict__[attrName] = member |
103 return self.__dict__[attrName] |
116 return member |
|
117 |
104 return PyroProxyProxy() |
118 return PyroProxyProxy() |
105 |
119 |
106 |
120 |