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 |