24 import traceback |
24 import traceback |
25 from time import sleep |
25 from time import sleep |
26 import copy |
26 import copy |
27 |
27 |
28 # this module attribute contains a list of DNS-SD (Zeroconf) service types |
28 # this module attribute contains a list of DNS-SD (Zeroconf) service types |
29 # supported by this connector plugin. |
29 # supported by this connector confnode. |
30 # |
30 # |
31 # for connectors that do not support DNS-SD, this attribute can be omitted |
31 # for connectors that do not support DNS-SD, this attribute can be omitted |
32 # or set to an empty list. |
32 # or set to an empty list. |
33 supported_dnssd_services = ["_PYRO._tcp.local."] |
33 supported_dnssd_services = ["_PYRO._tcp.local."] |
34 |
34 |
35 def PYRO_connector_factory(uri, pluginsroot): |
35 def PYRO_connector_factory(uri, confnodesroot): |
36 """ |
36 """ |
37 This returns the connector to Pyro style PLCobject |
37 This returns the connector to Pyro style PLCobject |
38 """ |
38 """ |
39 pluginsroot.logger.write(_("Connecting to URI : %s\n")%uri) |
39 confnodesroot.logger.write(_("Connecting to URI : %s\n")%uri) |
40 |
40 |
41 servicetype, location = uri.split("://") |
41 servicetype, location = uri.split("://") |
42 |
42 |
43 # Try to get the proxy object |
43 # Try to get the proxy object |
44 try : |
44 try : |
45 RemotePLCObjectProxy = pyro.getAttrProxyForURI("PYROLOC://"+location+"/PLCObject") |
45 RemotePLCObjectProxy = pyro.getAttrProxyForURI("PYROLOC://"+location+"/PLCObject") |
46 except Exception, msg: |
46 except Exception, msg: |
47 pluginsroot.logger.write_error(_("Wrong URI, please check it !\n")) |
47 confnodesroot.logger.write_error(_("Wrong URI, please check it !\n")) |
48 pluginsroot.logger.write_error(traceback.format_exc()) |
48 confnodesroot.logger.write_error(traceback.format_exc()) |
49 return None |
49 return None |
50 |
50 |
51 def PyroCatcher(func, default=None): |
51 def PyroCatcher(func, default=None): |
52 """ |
52 """ |
53 A function that catch a pyro exceptions, write error to logger |
53 A function that catch a pyro exceptions, write error to logger |
57 try: |
57 try: |
58 return func(*args,**kwargs) |
58 return func(*args,**kwargs) |
59 except Pyro.errors.ProtocolError, e: |
59 except Pyro.errors.ProtocolError, e: |
60 pass |
60 pass |
61 except Pyro.errors.ConnectionClosedError, e: |
61 except Pyro.errors.ConnectionClosedError, e: |
62 pluginsroot.logger.write_error("Connection lost!\n") |
62 confnodesroot.logger.write_error("Connection lost!\n") |
63 pluginsroot._connector = None |
63 confnodesroot._connector = None |
64 except Exception,e: |
64 except Exception,e: |
65 #pluginsroot.logger.write_error(traceback.format_exc()) |
65 #confnodesroot.logger.write_error(traceback.format_exc()) |
66 errmess = ''.join(Pyro.util.getPyroTraceback(e)) |
66 errmess = ''.join(Pyro.util.getPyroTraceback(e)) |
67 pluginsroot.logger.write_error(errmess+"\n") |
67 confnodesroot.logger.write_error(errmess+"\n") |
68 print errmess |
68 print errmess |
69 pluginsroot._connector = None |
69 confnodesroot._connector = None |
70 return default |
70 return default |
71 return catcher_func |
71 return catcher_func |
72 |
72 |
73 # Check connection is effective. |
73 # Check connection is effective. |
74 # lambda is for getattr of GetPLCstatus to happen inside catcher |
74 # lambda is for getattr of GetPLCstatus to happen inside catcher |
75 if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None: |
75 if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None: |
76 pluginsroot.logger.write_error(_("Cannot get PLC status - connection failed.\n")) |
76 confnodesroot.logger.write_error(_("Cannot get PLC status - connection failed.\n")) |
77 return None |
77 return None |
78 |
78 |
79 |
79 |
80 class PyroProxyProxy: |
80 class PyroProxyProxy: |
81 """ |
81 """ |
93 """ |
93 """ |
94 return RemotePLCObjectProxy |
94 return RemotePLCObjectProxy |
95 |
95 |
96 def _PyroStartPLC(self, *args, **kwargs): |
96 def _PyroStartPLC(self, *args, **kwargs): |
97 """ |
97 """ |
98 pluginsroot._connector.GetPyroProxy() is used |
98 confnodesroot._connector.GetPyroProxy() is used |
99 rather than RemotePLCObjectProxy because |
99 rather than RemotePLCObjectProxy because |
100 object is recreated meanwhile, |
100 object is recreated meanwhile, |
101 so we must not keep ref to it here |
101 so we must not keep ref to it here |
102 """ |
102 """ |
103 current_status = pluginsroot._connector.GetPyroProxy().GetPLCstatus() |
103 current_status = confnodesroot._connector.GetPyroProxy().GetPLCstatus() |
104 if current_status == "Dirty": |
104 if current_status == "Dirty": |
105 """ |
105 """ |
106 Some bad libs with static symbols may polute PLC |
106 Some bad libs with static symbols may polute PLC |
107 ask runtime to suicide and come back again |
107 ask runtime to suicide and come back again |
108 """ |
108 """ |
109 pluginsroot.logger.write(_("Force runtime reload\n")) |
109 confnodesroot.logger.write(_("Force runtime reload\n")) |
110 pluginsroot._connector.GetPyroProxy().ForceReload() |
110 confnodesroot._connector.GetPyroProxy().ForceReload() |
111 pluginsroot._Disconnect() |
111 confnodesroot._Disconnect() |
112 # let remote PLC time to resurect.(freeze app) |
112 # let remote PLC time to resurect.(freeze app) |
113 sleep(0.5) |
113 sleep(0.5) |
114 pluginsroot._Connect() |
114 confnodesroot._Connect() |
115 self.RemotePLCObjectProxyCopy = copy.copy(pluginsroot._connector.GetPyroProxy()) |
115 self.RemotePLCObjectProxyCopy = copy.copy(confnodesroot._connector.GetPyroProxy()) |
116 return pluginsroot._connector.GetPyroProxy().StartPLC(*args, **kwargs) |
116 return confnodesroot._connector.GetPyroProxy().StartPLC(*args, **kwargs) |
117 StartPLC = PyroCatcher(_PyroStartPLC, False) |
117 StartPLC = PyroCatcher(_PyroStartPLC, False) |
118 |
118 |
119 |
119 |
120 def _PyroGetTraceVariables(self): |
120 def _PyroGetTraceVariables(self): |
121 """ |
121 """ |
122 for safe use in from debug thread, must use the copy |
122 for safe use in from debug thread, must use the copy |
123 """ |
123 """ |
124 if self.RemotePLCObjectProxyCopy is None: |
124 if self.RemotePLCObjectProxyCopy is None: |
125 self.RemotePLCObjectProxyCopy = copy.copy(pluginsroot._connector.GetPyroProxy()) |
125 self.RemotePLCObjectProxyCopy = copy.copy(confnodesroot._connector.GetPyroProxy()) |
126 return self.RemotePLCObjectProxyCopy.GetTraceVariables() |
126 return self.RemotePLCObjectProxyCopy.GetTraceVariables() |
127 GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",None,None)) |
127 GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",None,None)) |
128 |
128 |
129 def _PyroGetPLCstatus(self): |
129 def _PyroGetPLCstatus(self): |
130 return RemotePLCObjectProxy.GetPLCstatus() |
130 return RemotePLCObjectProxy.GetPLCstatus() |