connectors/PYRO/__init__.py
changeset 3881 0b3ac94f494c
parent 3808 3e219f00151a
parent 3861 7e17f7e02a2b
equal deleted inserted replaced
3880:89549813a6c1 3881:0b3ac94f494c
    32 import Pyro5.client
    32 import Pyro5.client
    33 import Pyro5.errors
    33 import Pyro5.errors
    34 
    34 
    35 # TODO: PSK
    35 # TODO: PSK
    36 
    36 
    37 from runtime import PlcStatus
       
    38 import importlib
    37 import importlib
    39 
    38 
    40 
    39 
    41 Pyro5.config.SERIALIZER = "msgpack"
    40 Pyro5.config.SERIALIZER = "msgpack"
    42 
    41 
    62                 loc=location, ex=str(e)))
    61                 loc=location, ex=str(e)))
    63         return None
    62         return None
    64 
    63 
    65     RemotePLCObjectProxy._pyroTimeout = 60
    64     RemotePLCObjectProxy._pyroTimeout = 60
    66 
    65 
       
    66     class MissingCallException(Exception):
       
    67         pass
       
    68 
    67     def PyroCatcher(func, default=None):
    69     def PyroCatcher(func, default=None):
    68         """
    70         """
    69         A function that catch a Pyro exceptions, write error to logger
    71         A function that catch a Pyro exceptions, write error to logger
    70         and return default value when it happen
    72         and return default value when it happen
    71         """
    73         """
    75             except Pyro5.errors.ConnectionClosedError as e:
    77             except Pyro5.errors.ConnectionClosedError as e:
    76                 confnodesroot._SetConnector(None)
    78                 confnodesroot._SetConnector(None)
    77                 confnodesroot.logger.write_error(_("Connection lost!\n"))
    79                 confnodesroot.logger.write_error(_("Connection lost!\n"))
    78             except Pyro5.errors.ProtocolError as e:
    80             except Pyro5.errors.ProtocolError as e:
    79                 confnodesroot.logger.write_error(_("Pyro exception: %s\n") % e)
    81                 confnodesroot.logger.write_error(_("Pyro exception: %s\n") % e)
       
    82             except MissingCallException as e:
       
    83                 confnodesroot.logger.write_warning(_("Remote call not supported: %s\n") % e.message)
    80             except Exception as e:
    84             except Exception as e:
    81                 errmess = ''.join(Pyro5.errors.get_pyro_traceback())
    85                 errmess = ''.join(Pyro5.errors.get_pyro_traceback())
    82                 confnodesroot.logger.write_error(errmess + "\n")
    86                 confnodesroot.logger.write_error(errmess + "\n")
    83                 print(errmess)
    87                 print(errmess)
    84                 confnodesroot._SetConnector(None)
    88                 confnodesroot._SetConnector(None)
    92         confnodesroot.logger.write_warning(_("PLC did not provide identity and security infomation.\n"))
    96         confnodesroot.logger.write_warning(_("PLC did not provide identity and security infomation.\n"))
    93     else:
    97     else:
    94         ID, secret = IDPSK
    98         ID, secret = IDPSK
    95         PSK.UpdateID(confnodesroot.ProjectPath, ID, secret, uri)
    99         PSK.UpdateID(confnodesroot.ProjectPath, ID, secret, uri)
    96 
   100 
    97     _special_return_funcs = {
       
    98         "StartPLC": False,
       
    99         "GetTraceVariables": (PlcStatus.Broken, None),
       
   100         "GetPLCstatus": (PlcStatus.Broken, None),
       
   101         "RemoteExec": (-1, "RemoteExec script failed!")
       
   102     }
       
   103 
       
   104     class PyroProxyProxy(object):
   101     class PyroProxyProxy(object):
   105         """
   102         """
   106         A proxy proxy class to handle Beremiz Pyro interface specific behavior.
   103         A proxy proxy class to handle Beremiz Pyro interface specific behavior.
   107         And to put Pyro exception catcher in between caller and Pyro proxy
   104         And to put Pyro exception catcher in between caller and Pyro proxy
   108         """
   105         """
   109         def __getattr__(self, attrName):
   106         def __getattr__(self, attrName):
   110             member = self.__dict__.get(attrName, None)
   107             member = self.__dict__.get(attrName, None)
   111             if member is None:
   108             if member is None:
   112                 def my_local_func(*args, **kwargs):
   109                 def my_local_func(*args, **kwargs):
   113                     return RemotePLCObjectProxy.__getattr__(attrName)(*args, **kwargs)
   110                     call = RemotePLCObjectProxy.__getattr__(attrName)
   114                 member = PyroCatcher(my_local_func, _special_return_funcs.get(attrName, None))
   111                     if call is None:
       
   112                         raise MissingCallException(attrName)
       
   113                     else:
       
   114                         return call(*args, **kwargs)
       
   115                 member = PyroCatcher(my_local_func, self.PLCObjDefaults.get(attrName, None))
   115                 self.__dict__[attrName] = member
   116                 self.__dict__[attrName] = member
   116             return member
   117             return member
   117 
   118 
   118     return PyroProxyProxy
   119     return PyroProxyProxy