Beremiz.py
changeset 7 e20fa7257d41
parent 6 97d73990053d
child 8 56bae4ff53c4
equal deleted inserted replaced
6:97d73990053d 7:e20fa7257d41
    30 import os, re, platform, sys, time, traceback, getopt, commands
    30 import os, re, platform, sys, time, traceback, getopt, commands
    31 base_folder = os.path.split(sys.path[0])[0]
    31 base_folder = os.path.split(sys.path[0])[0]
    32 sys.path.append(os.path.join(base_folder, "plcopeneditor"))
    32 sys.path.append(os.path.join(base_folder, "plcopeneditor"))
    33 sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen"))
    33 sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen"))
    34 
    34 
       
    35 iec2cc_path = os.path.join(base_folder, "matiec", "iec2cc")
       
    36 ieclib_path = os.path.join(base_folder, "matiec", "lib")
       
    37 
    35 from PLCOpenEditor import PLCOpenEditor, ProjectDialog
    38 from PLCOpenEditor import PLCOpenEditor, ProjectDialog
    36 from PLCControler import PLCControler
    39 from PLCControler import PLCControler
    37 
    40 
    38 from networkedit import networkedit
    41 from networkedit import networkedit
    39 from nodelist import NodeList
    42 from nodelist import NodeList
    76 
    79 
    77 
    80 
    78 class LogPseudoFile:
    81 class LogPseudoFile:
    79     """ Base class for file like objects to facilitate StdOut for the Shell."""
    82     """ Base class for file like objects to facilitate StdOut for the Shell."""
    80     def __init__(self, output = None):
    83     def __init__(self, output = None):
       
    84         self.red_white = wx.TextAttr("RED", "WHITE")
       
    85         self.red_yellow = wx.TextAttr("RED", "YELLOW")
       
    86         self.black_white = wx.TextAttr("BLACK", "WHITE")
       
    87         self.default_style = None
    81         self.output = output
    88         self.output = output
    82 
    89 
    83     def writelines(self, l):
    90     def writelines(self, l):
    84         map(self.write, l)
    91         map(self.write, l)
    85 
    92 
    86     def write(self, s):
    93     def write(self, s):
    87         self.output.SetValue(self.output.GetValue() + s) 
    94         if self.default_style != self.black_white: 
       
    95             self.output.SetDefaultStyle(self.black_white)
       
    96             self.default_style = self.black_white
       
    97         self.output.AppendText(s) 
       
    98 
       
    99     def write_warning(self, s):
       
   100         if self.default_style != self.red_white: 
       
   101             self.output.SetDefaultStyle(self.red_white)
       
   102             self.default_style = self.red_white
       
   103         self.output.AppendText(s) 
       
   104 
       
   105     def write_error(self, s):
       
   106         if self.default_style != self.red_yellow: 
       
   107             self.output.SetDefaultStyle(self.red_yellow)
       
   108             self.default_style = self.red_yellow
       
   109         self.output.AppendText(s) 
    88 
   110 
    89     def flush(self):
   111     def flush(self):
    90         self.output.SetValue("")
   112         self.output.SetValue("")
    91     
   113     
    92     def isatty(self):
   114     def isatty(self):
   259         self.SetClientSize(wx.Size(600, 300))
   281         self.SetClientSize(wx.Size(600, 300))
   260         self.SetMenuBar(self.menuBar1)
   282         self.SetMenuBar(self.menuBar1)
   261         
   283         
   262         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   284         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
   263               name='LogConsole', parent=self, pos=wx.Point(0, 0),
   285               name='LogConsole', parent=self, pos=wx.Point(0, 0),
   264               size=wx.Size(0, 0), style=wx.TE_MULTILINE)
   286               size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
   265         
   287         
   266         self.EditPLCButton = wx.Button(id=ID_BEREMIZEDITPLCBUTTON, label='Edit\nPLC',
   288         self.EditPLCButton = wx.Button(id=ID_BEREMIZEDITPLCBUTTON, label='Edit\nPLC',
   267               name='EditPLCButton', parent=self, pos=wx.Point(0, 0),
   289               name='EditPLCButton', parent=self, pos=wx.Point(0, 0),
   268               size=wx.Size(48, 48), style=0)
   290               size=wx.Size(48, 48), style=0)
   269         self.EditPLCButton.Bind(wx.EVT_BUTTON, self.OnEditPLCButton,
   291         self.EditPLCButton.Bind(wx.EVT_BUTTON, self.OnEditPLCButton,
   615             self.PLCEditor.RefreshFileMenu()
   637             self.PLCEditor.RefreshFileMenu()
   616             self.PLCEditor.RefreshEditMenu()
   638             self.PLCEditor.RefreshEditMenu()
   617             self.PLCEditor.RefreshToolBar()
   639             self.PLCEditor.RefreshToolBar()
   618             self.PLCEditor.Show()
   640             self.PLCEditor.Show()
   619 
   641 
       
   642     def LogCommand(self, Command, sz_limit = 100):
       
   643 
       
   644         import os, popen2, fcntl, select, signal
       
   645         
       
   646         child = popen2.Popen3(Command, 1) # capture stdout and stderr from command
       
   647         child.tochild.close()             # don't need to talk to child
       
   648         outfile = child.fromchild 
       
   649         outfd = outfile.fileno()
       
   650         errfile = child.childerr
       
   651         errfd = errfile.fileno()
       
   652         outdata = errdata = ''
       
   653         outeof = erreof = 0
       
   654         outlen = errlen = 0
       
   655         while 1:
       
   656             ready = select.select([outfd,errfd],[],[]) # wait for input
       
   657             if outfd in ready[0]:
       
   658                 outchunk = outfile.readline()
       
   659                 if outchunk == '': outeof = 1
       
   660                 outdata += outchunk
       
   661                 outlen += 1
       
   662                 self.Log.write(outchunk)
       
   663             if errfd in ready[0]:
       
   664                 errchunk = errfile.readline()
       
   665                 if errchunk == '': erreof = 1
       
   666                 errdata += errchunk
       
   667                 errlen += 1
       
   668                 self.Log.write_warning(errchunk)
       
   669             if outeof and erreof : break
       
   670             if errlen > sz_limit or outlen > sz_limit : 
       
   671                 os.kill(child.pid, signal.SIGTERM)
       
   672                 self.Log.write_error("Output size reached limit -- killed\n")
       
   673                 break
       
   674         err = child.wait()
       
   675         return (err, outdata, errdata)
       
   676 
   620     def BuildAutom(self):
   677     def BuildAutom(self):
   621         if self.PLCManager:
   678         if self.PLCManager:
   622             self.TargetDir = os.path.join(self.CurrentProjectPath, "build")
   679             self.TargetDir = os.path.join(self.CurrentProjectPath, "build")
   623             if not os.path.exists(self.TargetDir):
   680             if not os.path.exists(self.TargetDir):
   624                 os.mkdir(self.TargetDir)
   681                 os.mkdir(self.TargetDir)
   625             self.Log.flush()
   682             self.Log.flush()
   626             sys.stdout = self.Log
   683             #sys.stdout = self.Log
   627             try:
   684             try:
   628                 print "Building ST Program..."
   685                 self.Log.write("Building ST Program...\n")
   629                 plc_file = os.path.join(self.TargetDir, "plc.st")
   686                 plc_file = os.path.join(self.TargetDir, "plc.st")
   630                 result = self.PLCManager.GenerateProgram(plc_file)
   687                 result = self.PLCManager.GenerateProgram(plc_file)
   631                 if not result:
   688                 if not result:
   632                     raise Exception
   689                     raise Exception, "ST/IL/SFC code generator returned %d"%result
   633                 print "Compiling ST Program in to C Program..."
   690                 self.Log.write("Compiling ST Program in to C Program...\n")
   634                 status, result = commands.getstatusoutput("../matiec/iec2cc %s -I ../matiec/lib %s"%(plc_file, self.TargetDir))
   691                 status, result, err_result = self.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, self.TargetDir))
   635                 if status:
   692                 if status:
   636                     print result
   693                     raise Exception, "IEC2C compiler returned %d"%status
   637                     raise Exception
   694                 self.Log.write("Extracting Located Variables...\n")
   638                 print "Extracting Located Variables..."
       
   639                 location_file = open(os.path.join(self.TargetDir,"LOCATED_VARIABLES.h"))
   695                 location_file = open(os.path.join(self.TargetDir,"LOCATED_VARIABLES.h"))
   640                 locations = []
   696                 locations = []
   641                 lines = [line.strip() for line in location_file.readlines()]
   697                 lines = [line.strip() for line in location_file.readlines()]
   642                 for line in lines:
   698                 for line in lines:
   643                     result = LOCATED_MODEL.match(line)
   699                     result = LOCATED_MODEL.match(line)
   644                     if result:
   700                     if result:
   645                         locations.append(result.groups())
   701                         locations.append(result.groups())
   646                 print "Generating Network Configurations..."
   702                 self.Log.write("Generating Network Configurations...\n")
   647                 for bus_id, bus_infos in self.BusManagers.items():
   703                 for bus_id, bus_infos in self.BusManagers.items():
   648                     if bus_infos["Type"] == "CanFestival":
   704                     if bus_infos["Type"] == "CanFestival":
   649                         master = config_utils.GenerateConciseDCF(locations, bus_id, bus_infos["NodeList"])
   705                         master = config_utils.GenerateConciseDCF(locations, bus_id, bus_infos["NodeList"])
   650                         result = gen_cfile.GenerateFile("%s.c"%os.path.join(self.TargetDir, gen_cfile.FormatName(bus_infos["Name"])), master)
   706                         result = gen_cfile.GenerateFile("%s.c"%os.path.join(self.TargetDir, gen_cfile.FormatName(bus_infos["Name"])), master)
   651                         if result:
   707                         if result:
   652                             raise Exception
   708                             raise Exception
   653                 print "Generating Makefiles..."
   709                 self.Log.write("Generating Makefiles...\n")
   654                 
   710                 
   655                 print "Compiling Project..."
   711                 self.Log.write("Compiling Project...\n")
   656                 
   712                 
   657                 print "\nBuild Project completed"
   713                 self.Log.write("\nBuild Project completed\n")
   658             except Exception, message:
   714             except Exception, message:
       
   715                 self.Log.write_error("\nBuild Failed\n")
       
   716                 self.Log.write(str(message))
   659                 pass
   717                 pass
   660             sys.stdout = sys.__stdout__
   718             #sys.stdout = sys.__stdout__
   661                 
   719                 
   662 #-------------------------------------------------------------------------------
   720 #-------------------------------------------------------------------------------
   663 #                             Add Bus Dialog
   721 #                             Add Bus Dialog
   664 #-------------------------------------------------------------------------------
   722 #-------------------------------------------------------------------------------
   665 
   723