Edouard@2270: #!/usr/bin/env python Edouard@2270: # -*- coding: utf-8 -*- Edouard@2270: Edouard@2270: # This file is part of Beremiz runtime. Edouard@2270: Edouard@2270: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD Edouard@2270: # Copyright (C) 2017: Andrey Skvortsov Edouard@2270: # Copyright (C) 2018: Edouard TISSERANT Edouard@2270: Edouard@2270: # See COPYING file for copyrights details. Edouard@2270: kinsamanka@3750: kinsamanka@3750: Edouard@2270: import sys Edouard@2603: import os Edouard@2270: edouard@3800: import Pyro5 edouard@3800: import Pyro5.server edouard@3800: Edouard@2270: import runtime Edouard@2270: from runtime.ServicePublisher import ServicePublisher Edouard@2270: edouard@3808: Pyro5.config.SERIALIZER = "msgpack" edouard@3808: edouard@3800: def make_pyro_exposed_stub(method_name): edouard@3800: stub = lambda self, *args, **kwargs: \ edouard@3805: getattr(self.plc_object_instance, method_name)(*args, **kwargs) edouard@3800: stub.__name__ = method_name edouard@3800: Pyro5.server.expose(stub) edouard@3800: return stub edouard@3800: edouard@3800: edouard@3800: class PLCObjectPyroAdapter(type("PLCObjectPyroStubs", (), { edouard@3800: name: make_pyro_exposed_stub(name) for name in [ edouard@3800: "AppendChunkToBlob", edouard@3800: "GetLogMessage", edouard@3800: "GetPLCID", edouard@3800: "GetPLCstatus", edouard@3800: "GetTraceVariables", edouard@3800: "MatchMD5", edouard@3800: "NewPLC", edouard@3800: "PurgeBlobs", edouard@3800: "RemoteExec", edouard@3800: "RepairPLC", edouard@3800: "ResetLogCount", edouard@3800: "SeedBlob", edouard@3800: "SetTraceVariablesList", edouard@3800: "StartPLC", edouard@3800: "StopPLC" edouard@3800: ] edouard@3800: })): edouard@3800: def __init__(self, plc_object_instance): edouard@3800: self.plc_object_instance = plc_object_instance edouard@3800: edouard@2309: Edouard@2476: class PyroServer(object): Edouard@2270: def __init__(self, servicename, ip_addr, port): Edouard@2270: self.continueloop = True Edouard@2270: self.daemon = None Edouard@2270: self.servicename = servicename Edouard@2270: self.ip_addr = ip_addr Edouard@2270: self.port = port Edouard@2270: self.servicepublisher = None Edouard@2603: self.piper, self.pipew = None, None Edouard@2270: Edouard@2270: def _to_be_published(self): Edouard@2270: return self.servicename is not None and \ Edouard@2311: self.ip_addr not in ["", "localhost", "127.0.0.1"] Edouard@2270: Edouard@2270: def PrintServerInfo(self): Edouard@2270: print(_("Pyro port :"), self.port) Edouard@2270: Edouard@2270: if self._to_be_published(): Edouard@2270: print(_("Publishing service on local network")) Edouard@2270: edouard@3843: if sys.stdout: edouard@3843: sys.stdout.flush() Edouard@2270: Edouard@2270: def PyroLoop(self, when_ready): edouard@2492: if self._to_be_published(): edouard@2492: self.Publish() edouard@2492: Edouard@2270: while self.continueloop: edouard@3800: self.daemon = Pyro5.server.Daemon(host=self.ip_addr, port=self.port) Edouard@2270: edouard@3800: self.daemon.register(PLCObjectPyroAdapter(runtime.GetPLCObjectSingleton()), "PLCObject") Edouard@2270: Edouard@2270: when_ready() edouard@3308: edouard@3800: self.daemon.requestLoop() edouard@3308: Edouard@2476: self.Unpublish() Edouard@2270: Edouard@2270: def Restart(self): Edouard@2476: self.daemon.shutdown(True) Edouard@2270: Edouard@2270: def Quit(self): Edouard@2270: self.continueloop = False edouard@3800: self.daemon.shutdown() edouard@3308: if not sys.platform.startswith('win'): edouard@3308: if self.pipew is not None: edouard@3308: os.write(self.pipew, "goodbye") Edouard@2270: Edouard@2476: def Publish(self): Edouard@2476: self.servicepublisher = ServicePublisher("PYRO") Edouard@2476: self.servicepublisher.RegisterService(self.servicename, Edouard@2476: self.ip_addr, self.port) Edouard@2476: Edouard@2476: def Unpublish(self): Edouard@2270: if self.servicepublisher is not None: Edouard@2270: self.servicepublisher.UnRegisterService() Edouard@2270: self.servicepublisher = None