Beremiz_service.py
changeset 2279 70143c20d2c0
parent 2249 602fdd08dfab
child 2270 d9175daf6522
child 2294 da288f63612f
equal deleted inserted replaced
2278:a3ac46366b86 2279:70143c20d2c0
    28 from __future__ import print_function
    28 from __future__ import print_function
    29 import os
    29 import os
    30 import sys
    30 import sys
    31 import getopt
    31 import getopt
    32 import threading
    32 import threading
    33 from threading import Thread, currentThread, Semaphore, Lock
    33 from threading import Thread, Semaphore, Lock
    34 import traceback
    34 import traceback
    35 import __builtin__
    35 import __builtin__
    36 import Pyro
    36 import Pyro
    37 import Pyro.core as pyro
    37 import Pyro.core as pyro
    38 
    38 
    43 
    43 
    44 def usage():
    44 def usage():
    45     print("""
    45     print("""
    46 Usage of Beremiz PLC execution service :\n
    46 Usage of Beremiz PLC execution service :\n
    47 %s {[-n servicename] [-i IP] [-p port] [-x enabletaskbar] [-a autostart]|-h|--help} working_dir
    47 %s {[-n servicename] [-i IP] [-p port] [-x enabletaskbar] [-a autostart]|-h|--help} working_dir
    48            -n        - zeroconf service name (default:disabled)
    48   -n  zeroconf service name (default:disabled)
    49            -i        - IP address of interface to bind to (default:localhost)
    49   -i  IP address of interface to bind to (default:localhost)
    50            -p        - port number default:3000
    50   -p  port number default:3000
    51            -h        - print this help text and quit
    51   -h  print this help text and quit
    52            -a        - autostart PLC (0:disable 1:enable) (default:0)
    52   -a  autostart PLC (0:disable 1:enable) (default:0)
    53            -x        - enable/disable wxTaskbarIcon (0:disable 1:enable) (default:1)
    53   -x  enable/disable wxTaskbarIcon (0:disable 1:enable) (default:1)
    54            -t        - enable/disable Twisted web interface (0:disable 1:enable) (default:1)
    54   -t  enable/disable Twisted web interface (0:disable 1:enable) (default:1)
    55            -w        - web server port or "off" to disable web server (default:8009)
    55   -w  web server port or "off" to disable web server (default:8009)
    56            -c        - WAMP client default config file (default:wampconf.json)
    56   -c  WAMP client config file (can be overriden by wampconf.json in project)
    57            -s        - WAMP client secret, given as a file
    57   -s  WAMP client secret, given as a file (can be overriden by wamp.secret in project)
    58            -e        - python extension (absolute path .py)
    58   -e  python extension (absolute path .py)
    59 
    59 
    60            working_dir - directory where are stored PLC files
    60            working_dir - directory where are stored PLC files
    61 """ % sys.argv[0])
    61 """ % sys.argv[0])
    62 
    62 
    63 
    63 
   497     if havewx:
   497     if havewx:
   498         reactor.registerWxApp(app)
   498         reactor.registerWxApp(app)
   499 
   499 
   500 if havewx:
   500 if havewx:
   501     wx_eval_lock = Semaphore(0)
   501     wx_eval_lock = Semaphore(0)
       
   502     # FIXME : beware wx mainloop is _not_ running in main thread
   502     # main_thread = currentThread()
   503     # main_thread = currentThread()
   503 
   504 
   504     def statuschangeTskBar(status):
   505     def statuschangeTskBar(status):
   505         wx.CallAfter(taskbar_instance.UpdateIcon, status)
   506         wx.CallAfter(taskbar_instance.UpdateIcon, status)
   506 
   507 
   510         tocall, args, kwargs = obj.call
   511         tocall, args, kwargs = obj.call
   511         obj.res = default_evaluator(tocall, *args, **kwargs)
   512         obj.res = default_evaluator(tocall, *args, **kwargs)
   512         wx_eval_lock.release()
   513         wx_eval_lock.release()
   513 
   514 
   514     def evaluator(tocall, *args, **kwargs):
   515     def evaluator(tocall, *args, **kwargs):
       
   516         # FIXME : should implement anti-deadlock
   515         # if main_thread == currentThread():
   517         # if main_thread == currentThread():
   516         #     # avoid dead lock if called from the wx mainloop
   518         #     # avoid dead lock if called from the wx mainloop
   517         #     return default_evaluator(tocall, *args, **kwargs)
   519         #     return default_evaluator(tocall, *args, **kwargs)
   518         # else:
   520         # else:
   519         o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
   521         o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
   569         self.run = run_with_except_hook
   571         self.run = run_with_except_hook
   570     threading.Thread.__init__ = init
   572     threading.Thread.__init__ = init
   571 
   573 
   572 
   574 
   573 installThreadExcepthook()
   575 installThreadExcepthook()
       
   576 havewamp = False
   574 
   577 
   575 if havetwisted:
   578 if havetwisted:
   576     if webport is not None:
   579     if webport is not None:
   577         try:
   580         try:
   578             import runtime.NevowServer as NS  # pylint: disable=ungrouped-imports
   581             import runtime.NevowServer as NS  # pylint: disable=ungrouped-imports
   579         except Exception, e:
   582         except Exception:
   580             print(_("Nevow/Athena import failed :"), e)
   583             LogMessageAndException(_("Nevow/Athena import failed :"))
   581             webport = None
   584             webport = None
   582         NS.WorkingDir = WorkingDir
   585         NS.WorkingDir = WorkingDir
   583 
   586 
   584     # Find pre-existing project WAMP config file
   587     try:
   585     _wampconf = os.path.join(WorkingDir, "wampconf.json")
   588         import runtime.WampClient as WC  # pylint: disable=ungrouped-imports
   586 
   589         WC.WorkingDir = WorkingDir
   587     # If project's WAMP config file exits, override default (-c)
   590         havewamp = True
   588     if os.path.exists(_wampconf):
   591     except Exception:
   589         wampconf = _wampconf
   592         LogMessageAndException(_("WAMP import failed :"))
   590 
       
   591     if wampconf is not None:
       
   592         try:
       
   593             import runtime.WampClient as WC  # pylint: disable=ungrouped-imports
       
   594         except Exception, e:
       
   595             print(_("WAMP import failed :"), e)
       
   596             wampconf = None
       
   597 
   593 
   598 # Load extensions
   594 # Load extensions
   599 for extention_file, extension_folder in extensions:
   595 for extention_file, extension_folder in extensions:
   600     sys.path.append(extension_folder)
   596     sys.path.append(extension_folder)
   601     execfile(os.path.join(extension_folder, extention_file), locals())
   597     execfile(os.path.join(extension_folder, extention_file), locals())
   603 if havetwisted:
   599 if havetwisted:
   604     if webport is not None:
   600     if webport is not None:
   605         try:
   601         try:
   606             website = NS.RegisterWebsite(webport)
   602             website = NS.RegisterWebsite(webport)
   607             pyruntimevars["website"] = website
   603             pyruntimevars["website"] = website
       
   604             NS.SetServer(pyroserver)
   608             statuschange.append(NS.website_statuslistener_factory(website))
   605             statuschange.append(NS.website_statuslistener_factory(website))
   609         except Exception:
   606         except Exception:
   610             LogMessageAndException(_("Nevow Web service failed. "))
   607             LogMessageAndException(_("Nevow Web service failed. "))
   611 
   608 
   612     if wampconf is not None:
   609     if havewamp:
   613         try:
   610         try:
   614             _wampconf = WC.LoadWampClientConf(wampconf)
   611             WC.SetServer(pyroserver)
   615             if _wampconf:
   612             WC.RegisterWampClient(wampconf, wampsecret)
   616                 if _wampconf["url"]:  # TODO : test more ?
   613             WC.RegisterWebSettings(NS)
   617                     WC.RegisterWampClient(wampconf, wampsecret)
       
   618                     pyruntimevars["wampsession"] = WC.GetSession
       
   619                     WC.SetServer(pyroserver)
       
   620                 else:
       
   621                     raise Exception(_("WAMP config is incomplete."))
       
   622             else:
       
   623                 raise Exception(_("WAMP config is missing."))
       
   624         except Exception:
   614         except Exception:
   625             LogMessageAndException(_("WAMP client startup failed. "))
   615             LogMessageAndException(_("WAMP client startup failed. "))
   626 
   616 
   627 pyro_thread_started = Lock()
   617 pyro_thread_started = Lock()
   628 pyro_thread_started.acquire()
   618 pyro_thread_started.acquire()