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() |