Beremiz_service.py
changeset 1984 081265cda5b1
parent 1955 a1ea9856013a
child 1987 8d1aca3c9e83
equal deleted inserted replaced
1983:edd7a3a06d86 1984:081265cda5b1
    33 from threading import Thread, currentThread, Semaphore
    33 from threading import Thread, currentThread, Semaphore
    34 import traceback
    34 import traceback
    35 import __builtin__
    35 import __builtin__
    36 import Pyro.core as pyro
    36 import Pyro.core as pyro
    37 
    37 
    38 from runtime import PLCObject, ServicePublisher
    38 from runtime import PLCObject, ServicePublisher, MainWorker
    39 import util.paths as paths
    39 import util.paths as paths
    40 
    40 
    41 
    41 
    42 def usage():
    42 def usage():
    43     print("""
    43     print("""
   399     return res
   399     return res
   400 
   400 
   401 
   401 
   402 class Server(object):
   402 class Server(object):
   403     def __init__(self, servicename, ip_addr, port,
   403     def __init__(self, servicename, ip_addr, port,
   404                  workdir, argv, autostart=False,
   404                  workdir, argv,
   405                  statuschange=None, evaluator=default_evaluator,
   405                  statuschange=None, evaluator=default_evaluator,
   406                  pyruntimevars=None):
   406                  pyruntimevars=None):
   407         self.continueloop = True
   407         self.continueloop = True
   408         self.daemon = None
   408         self.daemon = None
   409         self.servicename = servicename
   409         self.servicename = servicename
   411         self.port = port
   411         self.port = port
   412         self.workdir = workdir
   412         self.workdir = workdir
   413         self.argv = argv
   413         self.argv = argv
   414         self.plcobj = None
   414         self.plcobj = None
   415         self.servicepublisher = None
   415         self.servicepublisher = None
   416         self.autostart = autostart
       
   417         self.statuschange = statuschange
   416         self.statuschange = statuschange
   418         self.evaluator = evaluator
   417         self.evaluator = evaluator
   419         self.pyruntimevars = pyruntimevars
   418         self.pyruntimevars = pyruntimevars
   420 
   419 
   421     def Loop(self):
   420     def PyroLoop(self):
   422         while self.continueloop:
   421         while self.continueloop:
   423             pyro.initServer()
   422             pyro.initServer()
   424             self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
   423             self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
   425             # pyro never frees memory after connection close if no timeout set
   424             # pyro never frees memory after connection close if no timeout set
   426             # taking too small timeout value may cause
   425             # taking too small timeout value may cause
   427             # unwanted diconnection when IDE is kept busy for long periods
   426             # unwanted diconnection when IDE is kept busy for long periods
   428             self.daemon.setTimeout(60)
   427             self.daemon.setTimeout(60)
   429             self.Start()
   428 
       
   429             uri = self.daemon.connect(self.plcobj, "PLCObject")
       
   430 
       
   431             print(_("Pyro port :"), self.port)
       
   432             print(_("Pyro object's uri :"), uri)
       
   433 
       
   434             # Beremiz IDE detects daemon start by looking
       
   435             # for self.workdir in the daemon's stdout.
       
   436             # Therefore don't delete the following line
       
   437             print(_("Current working directory :"), self.workdir)
       
   438 
       
   439             # Configure and publish service
       
   440             # Not publish service if localhost in address params
       
   441             if self.servicename is not None and \
       
   442                self.ip_addr is not None and \
       
   443                self.ip_addr != "localhost" and \
       
   444                self.ip_addr != "127.0.0.1":
       
   445                 print(_("Publishing service on local network"))
       
   446                 self.servicepublisher = ServicePublisher.ServicePublisher()
       
   447                 self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port)
       
   448 
   430             self.daemon.requestLoop()
   449             self.daemon.requestLoop()
   431             self.daemon.sock.close()
   450             self.daemon.sock.close()
   432 
   451 
   433     def Restart(self):
   452     def Restart(self):
   434         self._stop()
   453         self._stop()
   438         if self.plcobj is not None:
   457         if self.plcobj is not None:
   439             self.plcobj.StopPLC()
   458             self.plcobj.StopPLC()
   440             self.plcobj.UnLoadPLC()
   459             self.plcobj.UnLoadPLC()
   441         self._stop()
   460         self._stop()
   442 
   461 
   443     def Start(self):
   462     def RegisterPLCObject(self, plcobj):
   444         self.plcobj = PLCObject(self.workdir, self.daemon, self.argv,
   463         self.plcobj = plcobj
   445                                 self.statuschange, self.evaluator,
       
   446                                 self.pyruntimevars)
       
   447 
       
   448         uri = self.daemon.connect(self.plcobj, "PLCObject")
       
   449 
       
   450         print(_("Pyro port :"), self.port)
       
   451         print(_("Pyro object's uri :"), uri)
       
   452 
       
   453         # Beremiz IDE detects daemon start by looking
       
   454         # for self.workdir in the daemon's stdout.
       
   455         # Therefore don't delete the following line
       
   456         print(_("Current working directory :"), self.workdir)
       
   457 
       
   458         # Configure and publish service
       
   459         # Not publish service if localhost in address params
       
   460         if self.servicename is not None and \
       
   461            self.ip_addr is not None and \
       
   462            self.ip_addr != "localhost" and \
       
   463            self.ip_addr != "127.0.0.1":
       
   464             print(_("Publishing service on local network"))
       
   465             self.servicepublisher = ServicePublisher.ServicePublisher()
       
   466             self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port)
       
   467 
       
   468         self.plcobj.AutoLoad()
       
   469         if self.plcobj.GetPLCstatus()[0] != "Empty":
       
   470             if self.autostart:
       
   471                 self.plcobj.StartPLC()
       
   472         self.plcobj.StatusChange()
       
   473 
       
   474         sys.stdout.flush()
       
   475 
   464 
   476     def _stop(self):
   465     def _stop(self):
   477         if self.plcobj is not None:
   466         if self.plcobj is not None:
   478             self.plcobj.StopPLC()
   467             self.plcobj.StopPLC()
   479         if self.servicepublisher is not None:
   468         if self.servicepublisher is not None:
   527             wx.CallAfter(wx_evaluator, o)
   516             wx.CallAfter(wx_evaluator, o)
   528             wx_eval_lock.acquire()
   517             wx_eval_lock.acquire()
   529             return o.res
   518             return o.res
   530 
   519 
   531     pyroserver = Server(servicename, given_ip, port,
   520     pyroserver = Server(servicename, given_ip, port,
   532                         WorkingDir, argv, autostart,
   521                         WorkingDir, argv,
   533                         statuschange, evaluator, pyruntimevars)
   522                         statuschange, evaluator, pyruntimevars)
   534 
   523 
   535     taskbar_instance = BeremizTaskBarIcon(pyroserver, enablewx)
   524     taskbar_instance = BeremizTaskBarIcon(pyroserver, enablewx)
   536 else:
   525 else:
   537     pyroserver = Server(servicename, given_ip, port,
   526     pyroserver = Server(servicename, given_ip, port,
   538                         WorkingDir, argv, autostart,
   527                         WorkingDir, argv,
   539                         statuschange, pyruntimevars=pyruntimevars)
   528                         statuschange, pyruntimevars=pyruntimevars)
   540 
   529 
   541 
   530 
   542 # Exception hooks
   531 # Exception hooks
   543 
   532 
   629             else:
   618             else:
   630                 raise Exception(_("WAMP config is missing."))
   619                 raise Exception(_("WAMP config is missing."))
   631         except Exception:
   620         except Exception:
   632             LogMessageAndException(_("WAMP client startup failed. "))
   621             LogMessageAndException(_("WAMP client startup failed. "))
   633 
   622 
       
   623 plcobj = PLCObject(pyroserver)
       
   624 
       
   625 plcobj.AutoLoad()
       
   626 if plcobj.GetPLCstatus()[0] == "Stopped":
       
   627     if autostart:
       
   628         plcobj.StartPLC()
       
   629 plcobj.StatusChange()
       
   630 
       
   631 pyro_thread = Thread(target=pyroserver.PyroLoop)
       
   632 pyro_thread.start()
       
   633 
       
   634 sys.stdout.flush()
   634 
   635 
   635 if havetwisted or havewx:
   636 if havetwisted or havewx:
   636     pyro_thread = Thread(target=pyroserver.Loop)
       
   637     pyro_thread.start()
       
   638 
       
   639     if havetwisted:
   637     if havetwisted:
   640         reactor.run()
   638         # reactor._installSignalHandlersAgain()
   641     elif havewx:
   639         def ui_thread_target():
   642         app.MainLoop()
   640             # FIXME: had to disable SignaHandlers install because 
   643 else:
   641             # signal not working in non-main thread
   644     try:
   642             reactor.run(installSignalHandlers=False)
   645         pyroserver.Loop()
   643     else :
   646     except KeyboardInterrupt:
   644         ui_thread_target = app.MainLoop
   647         pass
   645 
       
   646     ui_thread = Thread(target = ui_thread_target)
       
   647     ui_thread.start()
       
   648 
       
   649 try:
       
   650     MainWorker.runloop()
       
   651 except KeyboardInterrupt:
       
   652     pass
       
   653 
   648 pyroserver.Quit()
   654 pyroserver.Quit()
   649 sys.exit(0)
   655 sys.exit(0)