runtime/PLCObject.py
changeset 301 87c925eaaa3a
parent 299 d7f8ffe18017
child 302 d962b3d503b5
equal deleted inserted replaced
300:7f7912ae5ee8 301:87c925eaaa3a
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import Pyro.core as pyro
    25 import Pyro.core as pyro
    26 from threading import Timer, Thread
    26 from threading import Timer, Thread
    27 import ctypes, os, commands
    27 import ctypes, os, commands, types, sys
    28 import sys
    28 
    29 
    29 
    30 if os.name in ("nt", "ce"):
    30 if os.name in ("nt", "ce"):
    31     from _ctypes import LoadLibrary as dlopen
    31     from _ctypes import LoadLibrary as dlopen
    32     from _ctypes import FreeLibrary as dlclose
    32     from _ctypes import FreeLibrary as dlclose
    33 elif os.name == "posix":
    33 elif os.name == "posix":
    44     sys.stdout.write("PLCobject : "+message+"\n")
    44     sys.stdout.write("PLCobject : "+message+"\n")
    45     sys.stdout.flush()
    45     sys.stdout.flush()
    46 
    46 
    47 class PLCObject(pyro.ObjBase):
    47 class PLCObject(pyro.ObjBase):
    48     _Idxs = []
    48     _Idxs = []
    49     def __init__(self, workingdir, daemon, argv, statuschange=None):
    49     def __init__(self, workingdir, daemon, argv, statuschange=None, evaluator=eval):
    50         pyro.ObjBase.__init__(self)
    50         pyro.ObjBase.__init__(self)
       
    51         self.evaluator = evaluator
    51         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    52         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    52         self.workingdir = workingdir
    53         self.workingdir = workingdir
    53         self.PLCStatus = "Stopped"
    54         self.PLCStatus = "Stopped"
    54         self.PLClibraryHandle = None
    55         self.PLClibraryHandle = None
    55         # Creates fake C funcs proxies
    56         # Creates fake C funcs proxies
    56         self._FreePLC()
    57         self._FreePLC()
    57         self.daemon = daemon
    58         self.daemon = daemon
    58         self.statuschange = statuschange
    59         self.statuschange = statuschange
    59         self.python_threads_vars = None
    60         self.python_threads_vars = None
       
    61         self.hmi_frame = None
    60         
    62         
    61         # Get the last transfered PLC if connector must be restart
    63         # Get the last transfered PLC if connector must be restart
    62         try:
    64         try:
    63             self.CurrentPLCFilename=open(
    65             self.CurrentPLCFilename=open(
    64                              self._GetMD5FileName(),
    66                              self._GetMD5FileName(),
   179         return False
   181         return False
   180 
   182 
   181     def PrepareRuntimePy(self):
   183     def PrepareRuntimePy(self):
   182         self.python_threads_vars = globals().copy()
   184         self.python_threads_vars = globals().copy()
   183         pyfile = os.path.join(self.workingdir, "runtime.py")
   185         pyfile = os.path.join(self.workingdir, "runtime.py")
       
   186         hmifile = os.path.join(self.workingdir, "hmi.py")
   184         if os.path.exists(pyfile):
   187         if os.path.exists(pyfile):
   185             try:
   188             try:
   186                 # TODO handle exceptions in runtime.py
   189                 # TODO handle exceptions in runtime.py
   187                 # pyfile may redefine _runtime_cleanup
   190                 # pyfile may redefine _runtime_cleanup
   188                 # or even call _PythonThreadProc itself.
   191                 # or even call _PythonThreadProc itself.
       
   192                 if os.path.exists(hmifile):
       
   193                    execfile(hmifile, self.python_threads_vars)
   189                 execfile(pyfile, self.python_threads_vars)
   194                 execfile(pyfile, self.python_threads_vars)
       
   195                 try:
       
   196                    # try to instanciate the first frame found.
       
   197                    for name, obj in self.python_threads_vars.iteritems():
       
   198                        # obj is a class
       
   199                        if type(obj)==type(type) and issubclass(obj,self.python_threads_vars['wx'].Frame):
       
   200                            self.hmi_frame = obj(None)
       
   201                            self.python_threads_vars['_'+name] = self.hmi_frame
       
   202                            self.hmi_frame.Show()
       
   203                            break
       
   204                 except:
       
   205                     PLCprint(traceback.format_exc())
   190             except:
   206             except:
   191                 PLCprint(traceback.format_exc())
   207                 PLCprint(traceback.format_exc())
   192 
   208 
   193     def BeginRuntimePy(self):
   209     def BeginRuntimePy(self):
   194         runtime_begin = self.python_threads_vars.get("_runtime_begin",None)
   210         runtime_begin = self.python_threads_vars.get("_runtime_begin",None)
   195         if runtime_begin is not None:
   211         if runtime_begin is not None:
   196             runtime_begin()
   212             self.evaluator(runtime_begin)
   197 
   213 
   198     def FinishRuntimePy(self):
   214     def FinishRuntimePy(self):
   199         runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
   215         runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
   200         if runtime_cleanup is not None:
   216         if runtime_cleanup is not None:
   201             runtime_cleanup()
   217             self.evaluator(runtime_cleanup)
       
   218         if self.hmi_frame is not None:
       
   219             self.evaluator(self.hmi_frame.Destroy)
   202         self.python_threads_vars = None
   220         self.python_threads_vars = None
   203 
   221 
   204     def PythonThreadProc(self):
   222     def PythonThreadProc(self):
   205         PLCprint("PythonThreadProc started")
   223         PLCprint("PythonThreadProc started")
   206         self.BeginRuntimePy()
   224         self.BeginRuntimePy()
   210             cmd = self._PythonIterator(res)
   228             cmd = self._PythonIterator(res)
   211             #print " -> ", cmd
   229             #print " -> ", cmd
   212             if cmd is None:
   230             if cmd is None:
   213                 break
   231                 break
   214             try :
   232             try :
   215                 res = str(eval(cmd,self.python_threads_vars))
   233                 res = str(self.evaluator(eval,cmd,self.python_threads_vars))
   216             except Exception,e:
   234             except Exception,e:
   217                 res = "#EXCEPTION : "+str(e)
   235                 res = "#EXCEPTION : "+str(e)
   218                 PLCprint(res)
   236                 PLCprint(res)
   219         PLCprint("PythonThreadProc interrupted")
   237         PLCprint("PythonThreadProc interrupted")
   220     
   238     
   225             if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
   243             if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
   226                 if debug:
   244                 if debug:
   227                     self._resumeDebug()
   245                     self._resumeDebug()
   228                 self.PLCStatus = "Started"
   246                 self.PLCStatus = "Started"
   229                 self.StatusChange()
   247                 self.StatusChange()
   230                 self.PrepareRuntimePy()
   248                 self.evaluator(self.PrepareRuntimePy)
   231                 self.PythonThread = Thread(target=self.PythonThreadProc)
   249                 self.PythonThread = Thread(target=self.PythonThreadProc)
   232                 self.PythonThread.start()
   250                 self.PythonThread.start()
   233                 return True
   251                 return True
   234             else:
   252             else:
   235                 PLCprint("Problem starting PLC")
   253                 PLCprint("Problem starting PLC")