--- a/LPCManager.py Tue Jan 30 14:25:10 2018 +0100
+++ b/LPCManager.py Fri Feb 02 16:18:58 2018 +0100
@@ -22,6 +22,7 @@
from types import StringType, UnicodeType
+from util.BitmapLibrary import AddBitmapFolder # Path of directory containing current python file
_lpcmanager_path = os.path.split(__file__)[0]
@@ -30,93 +31,99 @@
PLC_GOT_module = ['GOT', 'GOT_111', 'GOT_131']
PLC_module = PLC_MC9_module + PLC_GOT_module
+# XXX get ride of global arch
- print "\nUsage of LPCManager.py :"
- print "\n %s Projectpath Buildpath port arch\n" % sys.argv[0]
+class LPCManagerLauncher(BeremizIDELauncher): + BeremizIDELauncher.__init__(self) + self.extensions = [os.path.join(_lpcmanager_path, "extention.py")] + "LPCProjectController", -# Command line arguments parsing
- opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
-except getopt.GetoptError:
- # print help information and exit:
-# asking for help causes exit
- if o in ("-h", "--help"):
+ print("\nUsage of LPCManager.py :") + print("\n %s Projectpath Buildpath port arch\n" % sys.argv[0])
+ def ProcessCommandLineArgs(self): + # Command line arguments parsing + opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) + except getopt.GetoptError: + # print help information and exit: -# BEREMIZ_DEBUG file detection in beremiz isn't enough (module scope)
-# here we set BMZ_DBG interpreter-wise, so that submodules can use it.
-__builtin__.__dict__["BMZ_DBG"] = os.path.exists("LPC_DEBUG")
-if wx.VERSION >= (3, 0, 0):
- app = wx.App(redirect=BMZ_DBG)
- app = wx.PySimpleApp(redirect=BMZ_DBG)
-app.SetAppName('beremiz')
-if wx.VERSION < (3, 0, 0):
- wx.InitAllImageHandlers()
+ # asking for help causes exit + if o in ("-h", "--help"): -from util.misc import InstallLocalRessources
-InstallLocalRessources(_beremiz_folder)
-from util.BitmapLibrary import AddBitmapFolder
-AddBitmapFolder(os.path.join(_lpcmanager_path, "images"))
+ self.projectOpen = args[0] + self.buildpath = args[1] + self.port = int(args[2]) -_lpcmanager_path = os.path.split(__file__)[0]
-from POULibrary import POULibrary
+ # overload with exacltly same code, but this is intended. + # we want extensions to use globals of this module, not Beremiz.py -class PLCLibraryLPC(POULibrary):
- def GetLibraryPath(self):
- return os.path.join(_lpcmanager_path + '/Pous/', "pousLPC.xml")
+ CMDpipe = StdoutPseudoFile(self.port) -class PLCLibraryGOT(POULibrary):
- def GetLibraryPath(self):
- return os.path.join(_lpcmanager_path + '/Pous/', "pousGOT.xml")
+ if self.projectOpen is not None: + self.projectOpen = self.BeremizIDE.DecodeFileSystemPath(self.projectOpen, False) -class PLCLibraryRTC(POULibrary):
- def GetLibraryPath(self):
- return os.path.join(_lpcmanager_path + '/Pous/', "pousRTC.xml")
+ CTR = self.LPCProjectController.LPCProjectController( + None, CMDpipe, self.buildpath) + if self.projectOpen is not None and os.path.isdir(self.projectOpen): + result = CTR.LoadProject(self.projectOpen) + CMDpipe.write("Error: Invalid project directory", result) + CMDpipe.write("Error: No such file or directory") -features.libraries=[('Native', 'NativeLib.NativeLibrary')]
+ lpcberemiz_cmd = LPCCommand(CTR, CMDpipe) + cmd_thread = Thread(target=lpcberemiz_cmd.cmdloop) + # TODO: join() when exiting -if arch in PLC_MC9_module:
- features.libraries += [('Python', 'py_ext.PythonLibrary'), ('RTC', lambda: PLCLibraryRTC)]
-elif arch in PLC_GOT_module:
- features.libraries += [('Python', 'py_ext.PythonLibrary'), ('RTC', lambda: PLCLibraryRTC), ('GOT', lambda: PLCLibraryGOT)]
- features.libraries += [('LPC', lambda: PLCLibraryLPC)]
+ self.frame = self.LPCBeremiz.LPCBeremiz(None, ctr=CTR) -features.catalog.pop([i for i, x in enumerate(features.catalog) if x[0].startswith('svg')][0])
+ # the "Show" command from composer does it instead + def CreateApplication(self): + # BEREMIZ_DEBUG file detection in beremiz isn't enough (module scope) + # here we set BMZ_DBG interpreter-wise, so that submodules can use it. + __builtin__.__dict__["BMZ_DBG"] = os.path.exists("LPC_DEBUG") -wxglade_hmi_index = [i for i, x in enumerate(features.catalog) if x[0].startswith('wxglade_hmi')][0]
-old_wxglade_hmi = features.catalog[wxglade_hmi_index]
-mwwxglade_hmi = ('wxglade_hmi', _('WxGlade GUI'), _('Add a simple WxGlade based GUI.'), 'MWWxglade_hmi.mwwxglade_hmi.WxGladeHMI')
-features.catalog[wxglade_hmi_index] = mwwxglade_hmi
+ BeremizIDELauncher.CreateApplication(self) -modbus_features = ('modbus', _('Modbus support'), _('Map located variables over Modbus'), 'modbus.modbus.RootClass')
-features.catalog.append(modbus_features)
+ # Add LPCmanager's image folder to searched ones. + AddBitmapFolder(os.path.join(_lpcmanager_path, "images")) from LPCconnector import LPC_connector_factory
@@ -1954,168 +1961,6 @@
-# -------------------------------------------------------------------------------
-# -------------------------------------------------------------------------------
-class LPCBeremiz(Beremiz):
- def _init_coll_FileMenu_Items(self, parent):
- config = wx.ConfigBase.Get()
- export = str(config.Read("Exporter"))
- config.Write("Exporter", '0')
- AppendMenu(parent, help='', id=wx.ID_SAVE,
- kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
- AppendMenu(parent, help='', id=wx.ID_CLOSE,
- kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
- parent.AppendSeparator()
- AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
- kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
- AppendMenu(parent, help='', id=wx.ID_PREVIEW,
- kind=wx.ITEM_NORMAL, text=_(u'Preview'))
- AppendMenu(parent, help='', id=wx.ID_PRINT,
- kind=wx.ITEM_NORMAL, text=_(u'Print'))
- parent.AppendSeparator()
- AppendMenu(parent, help='', id=ID_EXPORT,
- kind=wx.ITEM_NORMAL, text=_(u'Export'))
- parent.AppendSeparator()
- AppendMenu(parent, help='', id=wx.ID_EXIT,
- kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
- self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
- self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
- self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
- self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
- self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
- self.Bind(wx.EVT_MENU, lambda event: VariableWriter(self, event, self.CTR.ProjectPath), id=ID_EXPORT)
- self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
- self.AddToMenuToolBar([(wx.ID_SAVE, "save", _(u'Save'), None),
- (wx.ID_PRINT, "print", _(u'Print'), None)])
- def _init_ctrls(self, prnt):
- Beremiz._init_ctrls(self, prnt)
- def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
- self.ConfNodeInfos = {}
- Beremiz.__init__(self, parent, projectOpen, buildpath, ctr, debug)
- def Show(self, loading=True):
- # loading_splash = splash.SmartehScreenSplash(self, bitmap=GetPath(splash.SPLASH_FN), signal=signal_init)
- # thread = Thread(target=loading_splash.Show)
- def OnCloseFrame(self, event):
- if self.CheckSaveBeforeClosing(_("Close Application")):
- self.CTR.ResetAppFrame(lpcberemiz_cmd.Log)
- if self.CTR.OnlineMode == 0:
- self.CTR._SetConnector(None, False)
- self.CTR.KillDebugThread()
- self.KillLocalRuntime()
- # close wxGlade if running
- config = wx.ConfigBase.Get()
- wxGladePid = str(config.Read("BeremizRoot.wxGlade"))
- os.kill(int(wxGladePid), signal.SIGTERM)
- config.Write("BeremizRoot.wxGlade", str(wxGladePid))
- lpcberemiz_cmd.Log.write("Closed\n")
- def RefreshTitle(self):
- if self.CTR is not None:
- projectname = self.CTR.GetProjectName()
- if self.CTR.ProjectTestModified():
- projectname = "~%s~" % projectname
- self.SetTitle("%s - %s" % (name, projectname))
- def RefreshFileMenu(self):
- MenuToolBar = self.Panes["MenuToolBar"]
- if self.CTR is not None:
- selected = self.TabsOpened.GetSelection()
- graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
- if self.TabsOpened.GetPageCount() > 0:
- self.FileMenu.Enable(wx.ID_CLOSE, True)
- self.FileMenu.Enable(wx.ID_PREVIEW, True)
- self.FileMenu.Enable(wx.ID_PRINT, True)
- MenuToolBar.EnableTool(wx.ID_PRINT, True)
- self.FileMenu.Enable(wx.ID_PREVIEW, False)
- self.FileMenu.Enable(wx.ID_PRINT, False)
- MenuToolBar.EnableTool(wx.ID_PRINT, False)
- self.FileMenu.Enable(wx.ID_CLOSE, False)
- self.FileMenu.Enable(wx.ID_PREVIEW, False)
- self.FileMenu.Enable(wx.ID_PRINT, False)
- MenuToolBar.EnableTool(wx.ID_PRINT, False)
- self.FileMenu.Enable(wx.ID_PAGE_SETUP, True)
- project_modified = self.CTR.ProjectTestModified()
- self.FileMenu.Enable(wx.ID_SAVE, project_modified)
- MenuToolBar.EnableTool(wx.ID_SAVE, project_modified)
- self.FileMenu.Enable(wx.ID_CLOSE, False)
- self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
- self.FileMenu.Enable(wx.ID_PREVIEW, False)
- self.FileMenu.Enable(wx.ID_PRINT, False)
- MenuToolBar.EnableTool(wx.ID_PRINT, False)
- self.FileMenu.Enable(wx.ID_SAVE, False)
- MenuToolBar.EnableTool(wx.ID_SAVE, False)
- def RefreshScrollBars(self):
- xstart, ystart = self.PLCConfig.GetViewStart()
- window_size = self.PLCConfig.GetClientSize()
- sizer = self.PLCConfig.GetSizer()
- maxx, maxy = sizer.GetMinSize()
- posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
- posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
- self.PLCConfig.Scroll(posx, posy)
- self.PLCConfig.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
- maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
- Beremiz.RefreshAll(self)
- # Remove taskbar icon when simulating
- def StartLocalRuntime(self, taskbaricon=True):
- return Beremiz.StartLocalRuntime(self, taskbaricon=False)
def __init__(self, port):
@@ -2193,371 +2038,7 @@
-class LPCBeremiz_Cmd(cmd.Cmd):
- def __init__(self, CTR, Log):
- cmd.Cmd.__init__(self, stdin=Log, stdout=Log)
- self.use_rawinput = False
- self.restore_last_state = False
- def RestartTimer(self):
- if self.RefreshTimer is not None:
- self.RefreshTimer.cancel()
- self.RefreshTimer = Timer(0.1, wx.CallAfter, args=[self.Refresh])
- self.RefreshTimer.start()
- def do_EOF(self, line):
- def Show(self, loading=False):
- self.CTR.SetAppFrame(frame, frame.Log)
- self.CTR.UpdateMethodsFromPLCStatus()
- self.restore_last_state = True
- if self.restore_last_state:
- self.restore_last_state = False
- frame.RestoreLastState()
- frame._Refresh(TITLE, PROJECTTREE, POUINSTANCEVARIABLESPANEL, FILEMENU, EDITMENU)
- self.CTR.ResetAppFrame(self.Log)
- def SetProjectProperties(self, projectname, productname, productversion, companyname):
- "projectName": projectname,
- "productName": productname,
- "productVersion": productversion,
- "companyName": companyname}
- self.CTR.SetProjectProperties(properties=new_properties, buffer=False)
- def SetOnlineMode(self, mode, path=None):
- self.CTR.SetOnlineMode(mode, path)
- def AddBus(self, iec_channel, name, icon=None):
- for child in self.CTR.IterChildren():
- if child.BaseParams.getName() == name:
- return "Error: A bus named %s already exists\n" % name
- elif child.BaseParams.getIEC_Channel() == iec_channel:
- return "Error: A bus with IEC_channel %d already exists\n" % iec_channel
- bus = self.CTR.CTNAddChild(name, "LPCBus", iec_channel)
- return "Error: Unable to create bus\n"
- def RenameBus(self, iec_channel, name):
- bus = self.CTR.GetChildByIECLocation((iec_channel,))
- return "Error: No bus found\n"
- for child in self.CTR.IterChildren():
- if child != bus and child.BaseParams.getName() == name:
- return "Error: A bus named %s already exists\n" % name
- bus.BaseParams.setName(name)
- def ChangeBusIECChannel(self, old_iec_channel, new_iec_channel):
- bus = self.CTR.GetChildByIECLocation((old_iec_channel,))
- return "Error: No bus found\n"
- for child in self.CTR.IterChildren():
- if child != bus and child.BaseParams.getIEC_Channel() == new_iec_channel:
- return "Error: A bus with IEC_channel %d already exists\n" % new_iec_channel
- if wx.GetApp() is None:
- self.CTR.UpdateProjectVariableLocation(str(old_iec_channel),
- self.CTR.UpdateProjectVariableLocation(
- bus.BaseParams.setIEC_Channel(new_iec_channel)
- def RemoveBus(self, iec_channel):
- bus = self.CTR.GetChildByIECLocation((iec_channel,))
- return "Error: No bus found\n"
- self.CTR.RemoveProjectVariableByFilter(str(iec_channel))
- self.CTR.Children["LPCBus"].remove(bus)
- def AddModule(self, parent, iec_channel, name, icode, icon=None):
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- for child in GetModuleChildren(module):
- if child["name"] == name:
- return "Error: A module named %s already exists\n" % name
- elif child["IEC_Channel"] == iec_channel:
- return "Error: A module with IEC_channel %d already exists\n" % iec_channel
- GetLastModuleGroup(module).append({"name": name,
- "type": LOCATION_MODULE,
- "IEC_Channel": iec_channel,
- def RenameModule(self, iec_location, name):
- module = self.CTR.GetChildByIECLocation(iec_location)
- return "Error: No module found\n"
- parent = self.CTR.GetChildByIECLocation(iec_location[:-1])
- return "Error: No module found\n"
- if module["name"] != name:
- for child in GetModuleChildren(parent):
- if child["name"] == name:
- return "Error: A module named %s already exists\n" % name
- def ChangeModuleIECChannel(self, old_iec_location, new_iec_channel):
- module = self.CTR.GetChildByIECLocation(old_iec_location)
- return "Error: No module found\n"
- parent = self.CTR.GetChildByIECLocation(old_iec_location[:-1])
- return "Error: No module found\n"
- if module["IEC_Channel"] != new_iec_channel:
- for child in GetModuleChildren(parent):
- if child["IEC_Channel"] == new_iec_channel:
- return "Error: A module with IEC_channel %d already exists\n" % new_iec_channel
- self.CTR.UpdateProjectVariableLocation(".".join(map(str, old_iec_location)),
- ".".join(map(str, old_iec_location[:1] + (new_iec_channel,))))
- module["IEC_Channel"] = new_iec_channel
- def ChangeModuleInitCode(self, iec_location, icode):
- module = self.CTR.GetChildByIECLocation(iec_location)
- return "Error: No module found\n"
- def RemoveModule(self, parent, iec_channel):
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- child = GetModuleBySomething(module, "IEC_Channel", (iec_channel,))
- return "Error: No module found\n"
- self.CTR.RemoveProjectVariableByFilter(".".join(map(str, parent + (iec_channel,))))
- RemoveModuleChild(module, child)
- def StartGroup(self, parent, name, icon=None):
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- for child in module["children"]:
- if child["type"] == LOCATION_GROUP and child["name"] == name:
- return "Error: A group named %s already exists\n" % name
- module["children"].append({"name": name,
- "type": LOCATION_GROUP,
- def AddVariable(self, parent, location, name, direction, type, rcode, pcode, description=""):
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- for child in GetModuleChildren(module):
- if child["name"] == name:
- return "Error: A variable named %s already exists\n" % name
- if child["location"] == location and child["type"] == LOCATION_TYPES[direction]:
- return "Error: A variable with location %s already exists\n" % ".".join(map(str, location))
- GetLastModuleGroup(module).append({"name": name,
- "type": LOCATION_TYPES[direction],
- "description": description,
- def ChangeVariableParams(self, parent, location, new_name, new_direction, new_type, new_rcode, new_pcode,
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- for child in GetModuleChildren(module):
- if child["location"] == location and child["type"] == LOCATION_TYPES[new_direction]:
- elif child["name"] == new_name:
- return "Error: A variable named %s already exists\n" % new_name
- return "Error: No variable found\n"
- if variable["name"] != new_name:
- self.CTR.UpdateProjectVariableName(variable["name"], new_name)
- variable["name"] = new_name
- variable["type"] = LOCATION_TYPES[new_direction]
- variable["IEC_type"] = new_type
- variable["retrieve"] = new_rcode
- variable["publish"] = new_pcode
- if new_description is not None:
- variable["description"] = new_description
- def RemoveVariable(self, parent, location, direction):
- module = self.CTR.GetChildByIECLocation(parent)
- return "Error: No parent found\n"
- child = GetModuleVariable(module, location, direction)
- return "Error: No variable found\n"
- size = LOCATION_SIZES[self.CTR.GetBaseType(child["IEC_type"])]
- address = "%" + LOCATION_DIRS[child["type"]] + size + ".".join(map(str, parent + location))
- self.CTR.RemoveProjectVariableByAddress(address)
- RemoveModuleChild(module, child)
- return tuple(map(int, loc.split(".")))
-def GetCmdFunction(function, arg_types, opt=0):
- arg_number = len(arg_types)
- def CmdFunction(self, line):
- args_toks = line.split('"')
- if len(args_toks) % 2 == 0:
- self.Log.write("Error: Invalid command\n")
- for num, arg in enumerate(args_toks):
- args.extend(stripped.split(" "))
- if opt == 0 and len(args) != arg_number:
- elif len(args) > arg_number:
- elif len(args) < arg_number - opt:
- number = arg_number - opt
- self.Log.write("Error: No argument%s expected\n" % extra)
- self.Log.write("Error: 1 argument%s expected\n" % extra)
- self.Log.write("Error: %d arguments%s expected\n" % (number, extra))
- for num, arg in enumerate(args):
- args[num] = arg_types[num](arg)
- self.Log.write("Error: Invalid value for argument %d\n" % (num + 1))
- func = getattr(self, function)
- res = evaluator(func, *args)
- cmdlog.append((function, line, res))
- if len(cmdlog) > 100: # prevent debug log to grow too much
- if isinstance(res, (StringType, UnicodeType)):
-def CmdThreadProc(CTR, Log):
- for function, (arg_types, opt) in {"Exit": ([], 0),
- "SetProjectProperties": ([str, str, str, str], 0),
- "SetOnlineMode": ([str, str], 1),
- "AddBus": ([int, str, str], 1),
- "RenameBus": ([int, str], 0),
- "ChangeBusIECChannel": ([int, int], 0),
- "RemoveBus": ([int], 0),
- "AddModule": ([location, int, str, str, str], 1),
- "RenameModule": ([location, str], 0),
- "ChangeModuleIECChannel": ([location, int], 0),
- "ChangeModuleInitCode": ([location, str], 0),
- "RemoveModule": ([location, int], 0),
- "StartGroup": ([location, str, str], 1),
- "AddVariable": ([location, location, str, str, str, str, str, str], 1),
- "ChangeVariableParams": (
- [location, location, str, str, str, str, str, str], 1),
- "RemoveVariable": ([location, location], 0)}.iteritems():
- setattr(LPCBeremiz_Cmd, "do_%s" % function, GetCmdFunction(function, arg_types, opt))
- lpcberemiz_cmd = LPCBeremiz_Cmd(CTR, Log)
- lpcberemiz_cmd.cmdloop()
if __name__ == '__main__':
- Log = StdoutPseudoFile(port)
- if projectOpen is not None:
- projectOpen = DecodeFileSystemPath(projectOpen, False)
- CTR = LPCProjectController(None, Log, buildpath)
- if projectOpen is not None and os.path.isdir(projectOpen):
- result = CTR.LoadProject(projectOpen)
- Log.write("Error: Invalid project directory", result)
- Log.write("Error: No such file or directory")
- cmd_thread = Thread(target=CmdThreadProc, args=[CTR, Log])
- # Install a exception handle for bug reports
- import util.ExceptionHandler
- util.ExceptionHandler.AddExceptHook(version.app_version)
- frame = LPCBeremiz(None, ctr=CTR, debug=True)
+ lpcmanager = LPCManagerLauncher()