class HondaECU_ControlPanel(wx.Frame): def __init__(self, version_full, nobins=False, restrictions=None, force_restrictions=False): self.nobins = nobins self.restrictions = restrictions self.force_restrictions = force_restrictions self.run = True self.active_ftdi_device = None self.ftdi_devices = {} self.__clear_data() if getattr(sys, 'frozen', False): self.basepath = sys._MEIPASS else: self.basepath = os.path.dirname(os.path.realpath(__file__)) self.version_full = version_full self.version_short = self.version_full.split("-")[0] self.apps = { "flash": { "label": "Flash", "icon": "images/chip2.png", "conflicts": ["data", "hrc"], "panel": HondaECU_FlashPanel, "disabled": True, "enable": [ ECUSTATE.OK, ECUSTATE.RECOVER_OLD, ECUSTATE.RECOVER_NEW, ECUSTATE.WRITEx00, ECUSTATE.WRITEx30, ECUSTATE.READ ], }, "tunehelper": { "label": "Tune", "icon": "images/bike.png", "panel": HondaECU_TunePanelHelper, }, "info": { "label": "ECU Info", "icon": "images/info2.png", "conflicts": ["flash", "hrc"], "panel": HondaECU_InfoPanel, }, "data": { "label": "Data Logging", "icon": "images/monitor.png", "conflicts": ["flash", "hrc"], "panel": HondaECU_DatalogPanel, "disabled": True, "enable": [ECUSTATE.OK], }, "dtc": { "label": "Trouble Codes", "icon": "images/warning.png", "conflicts": ["flash", "hrc"], "panel": HondaECU_ErrorPanel, "disabled": True, "enable": [ECUSTATE.OK], }, # "hrcsettings": { # "label":"HRC Settings", # "icon":"images/cog.png", # "conflicts":["flash","data","dtc","info"], # "panel":HondaECU_HRCDataSettingsPanel, # "disabled":True, # "enable": [ECUSTATE.OK], # }, } self.appanels = {} wx.Frame.__init__(self, None, title="HondaECU %s :: Control Panel" % (self.version_short), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER, size=(500, 300)) ib = wx.IconBundle() ib.AddIcon(os.path.join(self.basepath, "images", "honda.ico")) self.SetIcons(ib) self.menubar = wx.MenuBar() self.SetMenuBar(self.menubar) fileMenu = wx.Menu() self.menubar.Append(fileMenu, '&File') self.devicesMenu = wx.Menu() fileMenu.AppendSubMenu(self.devicesMenu, "Devices") fileMenu.AppendSeparator() quitItem = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+Q') self.Bind(wx.EVT_MENU, self.OnClose, quitItem) fileMenu.Append(quitItem) helpMenu = wx.Menu() self.menubar.Append(helpMenu, '&Help') debugItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Show debug log') self.Bind(wx.EVT_MENU, self.OnDebug, debugItem) helpMenu.Append(debugItem) helpMenu.AppendSeparator() detectmapItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Detect map id') self.Bind(wx.EVT_MENU, self.OnDetectMap, detectmapItem) helpMenu.Append(detectmapItem) checksumItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Validate bin checksum') self.Bind(wx.EVT_MENU, self.OnBinChecksum, checksumItem) helpMenu.Append(checksumItem) self.statusbar = self.CreateStatusBar(1) self.statusbar.SetSize((-1, 28)) self.statusbar.SetStatusStyles([wx.SB_SUNKEN]) self.SetStatusBar(self.statusbar) self.outerp = wx.Panel(self) self.wrappanel = wx.Panel(self.outerp) wrapsizer = wx.WrapSizer(wx.HORIZONTAL) self.appbuttons = {} for a, d in self.apps.items(): icon = wx.Image(os.path.join(self.basepath, d["icon"]), wx.BITMAP_TYPE_ANY).ConvertToBitmap() enablestates = None if "enable" in d: enablestates = d["enable"] self.appbuttons[a] = HondaECU_AppButton(a, enablestates, self.wrappanel, wx.ID_ANY, icon, label=d["label"]) if "disabled" in d and d["disabled"]: self.appbuttons[a].Disable() wrapsizer.Add(self.appbuttons[a], 0) self.Bind(wx.EVT_BUTTON, self.OnAppButtonClicked, self.appbuttons[a]) self.wrappanel.SetSizer(wrapsizer) self.outersizer = wx.BoxSizer(wx.VERTICAL) self.outersizer.Add(self.wrappanel, 1, wx.EXPAND) self.outerp.SetSizer(self.outersizer) self.mainsizer = wx.BoxSizer(wx.VERTICAL) self.mainsizer.Add(self.outerp, 1, wx.EXPAND) self.SetSizer(self.mainsizer) self.Bind(wx.EVT_CLOSE, self.OnClose) self.debuglog = HondaECU_LogPanel(self) dispatcher.connect(self.USBMonitorHandler, signal="USBMonitor", sender=dispatcher.Any) dispatcher.connect(self.AppPanelHandler, signal="AppPanel", sender=dispatcher.Any) dispatcher.connect(self.KlineWorkerHandler, signal="KlineWorker", sender=dispatcher.Any) dispatcher.connect(self.TunePanelHelperHandler, signal="TunePanelHelper", sender=dispatcher.Any) self.usbmonitor = USBMonitor(self) self.klineworker = KlineWorker(self) self.Layout() self.mainsizer.Fit(self) self.Center() self.Show() self.usbmonitor.start() self.klineworker.start() def __clear_data(self): self.ecuinfo = {} def TunePanelHelperHandler(self, xdf, bin, metainfo, htf=None): if htf != None: tar = tarfile.open(htf, "r:xz") xdfs = None binorig = None binmod = None metainfo = None for f in tar.getnames(): if f == "metainfo.json": metainfo = json.load(tar.extractfile(f)) else: b, e = os.path.splitext(f) if e == ".xdf": xdfs = tar.extractfile(f).read() elif e == ".bin": x, y = os.path.splitext(b) if y == ".orig": binorig = tar.extractfile(f).read() elif y == ".mod": binmod = tar.extractfile(f).read() if xdfs != None and binorig != None and binmod != None and metainfo != None: tp = TunePanel(self, metainfo, xdfs, binorig, binmod) else: fbin = open(bin, "rb") byts = bytearray(fbin.read(os.path.getsize(bin))) fbin.close() fbin = open(xdf, "rb") xdfs = fbin.read(os.path.getsize(xdf)) fbin.close() tp = TunePanel(self, metainfo, xdfs, byts) def KlineWorkerHandler(self, info, value): if info in ["ecmid", "flashcount", "dtc", "dtccount", "state"]: self.ecuinfo[info] = value if info == "state": for a, d in self.apps.items(): if "enable" in d: if value in d["enable"]: self.appbuttons[a].Enable() else: self.appbuttons[a].Disable() elif info == "data": if not info in self.ecuinfo: self.ecuinfo[info] = {} self.ecuinfo[info][value[0]] = value[1:] def OnClose(self, event): self.run = False self.usbmonitor.join() self.klineworker.join() for w in wx.GetTopLevelWindows(): w.Destroy() def OnDetectMap(self, event): with wx.FileDialog(self, "Open ECU dump file", wildcard="ECU dump (*.bin)|*.bin", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return pathname = fileDialog.GetPath() ecupn = os.path.splitext(os.path.split(pathname)[-1])[0] for i in ECM_IDs.values(): if ecupn == i["pn"] and "keihinaddr" in i: fbin = open(pathname, "rb") nbyts = os.path.getsize(pathname) byts = bytearray(fbin.read(nbyts)) fbin.close() idadr = int(i["keihinaddr"], 16) self.statusbar.SetStatusText( "Map ID: " + byts[idadr:(idadr + 7)].decode("ascii"), 0) return self.statusbar.SetStatusText("Map ID: unknown", 0) def OnBinChecksum(self, event): with wx.FileDialog(self, "Open ECU dump file", wildcard="ECU dump (*.bin)|*.bin", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return pathname = fileDialog.GetPath() fbin = open(pathname, "rb") nbyts = os.path.getsize(pathname) byts = bytearray(fbin.read(nbyts)) fbin.close() self.statusbar.SetStatusText( "Checksum: %s" % ("good" if checksum8bitHonda(byts) == 0 else "bad"), 0) return def OnDebug(self, event): self.debuglog.Show() def OnAppButtonClicked(self, event): b = event.GetEventObject() if not b.appid in self.appanels: enablestates = None if "enable" in self.apps[b.appid]: enablestates = self.apps[b.appid]["enable"] self.appanels[b.appid] = self.apps[b.appid]["panel"]( self, b.appid, self.apps[b.appid], enablestates) self.appbuttons[b.appid].Disable() self.appanels[b.appid].Raise() def USBMonitorHandler(self, action, vendor, product, serial): dirty = False if action == "add": if not serial in self.ftdi_devices: self.ftdi_devices[serial] = (vendor, product) dirty = True elif action == "remove": if serial in self.ftdi_devices: if serial == self.active_ftdi_device: dispatcher.send(signal="FTDIDevice", sender=self, action="deactivate", vendor=vendor, product=product, serial=serial) self.active_ftdi_device = None self.__clear_data() del self.ftdi_devices[serial] dirty = True if len(self.ftdi_devices) > 0: if not self.active_ftdi_device: self.active_ftdi_device = list(self.ftdi_devices.keys())[0] dispatcher.send(signal="FTDIDevice", sender=self, action="activate", vendor=vendor, product=product, serial=serial) dirty = True else: pass if dirty: for i in self.devicesMenu.GetMenuItems(): self.devicesMenu.Remove(i) for s in self.ftdi_devices: rb = self.devicesMenu.AppendRadioItem( wx.ID_ANY, "%s : %s : %s" % (self.ftdi_devices[s][0], self.ftdi_devices[s][1], s)) self.Bind(wx.EVT_MENU, self.OnDeviceSelected, rb) if self.active_ftdi_device: self.statusbar.SetStatusText( "%s : %s : %s" % (self.ftdi_devices[self.active_ftdi_device][0], self.ftdi_devices[self.active_ftdi_device][1], self.active_ftdi_device), 0) self.devicesMenu.FindItemByPosition( list(self.ftdi_devices.keys()).index( self.active_ftdi_device)).Check() else: self.statusbar.SetStatusText("", 0) def OnDeviceSelected(self, event): s = list(self.ftdi_devices.keys())[[ m.IsChecked() for m in event.GetEventObject().GetMenuItems() ].index(True)] if s != self.active_ftdi_device: if self.active_ftdi_device != None: dispatcher.send( signal="FTDIDevice", sender=self, action="deactivate", vendor=self.ftdi_devices[self.active_ftdi_device], product=self.ftdi_devices[self.active_ftdi_device], serial=self.active_ftdi_device) self.__clear_data() self.active_ftdi_device = s dispatcher.send(signal="FTDIDevice", sender=self, action="activate", vendor=self.ftdi_devices[self.active_ftdi_device], product=self.ftdi_devices[self.active_ftdi_device], serial=self.active_ftdi_device) self.statusbar.SetStatusText( "%s : %s : %s" % (self.ftdi_devices[self.active_ftdi_device][0], self.ftdi_devices[self.active_ftdi_device][1], self.active_ftdi_device), 0) def AppPanelHandler(self, appid, action): if action == "close": if appid in self.appanels: del self.appanels[appid] self.appbuttons[appid].Enable()
class HondaECU_ControlPanel(wx.Frame): def __init__(self, version_full, nobins=False, restrictions=None, force_restrictions=False): self.prefsdir = user_data_dir("HondaECU", "MCUInnovationsInc") if not os.path.exists(self.prefsdir): os.makedirs(self.prefsdir) self.configfile = os.path.join(self.prefsdir, 'hondaecu.ini') self.config = configparser.ConfigParser() if os.path.isfile(self.configfile): self.config.read(self.configfile) if not "retries" in self.config['DEFAULT']: self.config['DEFAULT'] = {'retries': '1'} self.nobins = nobins self.restrictions = restrictions self.force_restrictions = force_restrictions self.run = True self.active_ftdi_device = None self.ftdi_devices = {} self.__clear_data() if getattr(sys, 'frozen', False): self.basepath = sys._MEIPASS else: self.basepath = os.path.dirname(os.path.realpath(__file__)) self.version_full = version_full self.version_short = self.version_full.split("-")[0] self.apps = { "flash": { "label": "Flash", "panel": HondaECU_FlashPanel, }, # "hrc": { # "label":"HRC Data Settings", # "panel":HondaECU_HRCDataSettingsPanel, # }, "data": { "label": "Data Logging", "panel": HondaECU_DatalogPanel, }, "dtc": { "label": "Trouble Codes", "panel": HondaECU_ErrorPanel, }, } self.appanels = {} wx.Frame.__init__(self, None, title="HondaECU %s" % (self.version_short), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER, size=(500, 300)) ib = wx.IconBundle() ib.AddIcon(os.path.join(self.basepath, "images", "honda.ico")) self.SetIcons(ib) self.menubar = wx.MenuBar() self.SetMenuBar(self.menubar) fileMenu = wx.Menu() self.menubar.Append(fileMenu, '&File') quitItem = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+Q') self.Bind(wx.EVT_MENU, self.OnClose, quitItem) fileMenu.Append(quitItem) helpMenu = wx.Menu() self.menubar.Append(helpMenu, '&Help') debugItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Show debug log') self.Bind(wx.EVT_MENU, self.OnDebug, debugItem) helpMenu.Append(debugItem) helpMenu.AppendSeparator() detectmapItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Detect map id') self.Bind(wx.EVT_MENU, self.OnDetectMap, detectmapItem) helpMenu.Append(detectmapItem) checksumItem = wx.MenuItem(helpMenu, wx.ID_ANY, 'Validate bin checksum') self.Bind(wx.EVT_MENU, self.OnBinChecksum, checksumItem) helpMenu.Append(checksumItem) self.statusicons = [ wx.Image(os.path.join(self.basepath, "images/bullet_black.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap(), wx.Image(os.path.join(self.basepath, "images/bullet_yellow.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap(), wx.Image(os.path.join(self.basepath, "images/bullet_green.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap(), wx.Image(os.path.join(self.basepath, "images/bullet_blue.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap(), wx.Image(os.path.join(self.basepath, "images/bullet_purple.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap(), wx.Image(os.path.join(self.basepath, "images/bullet_red.png"), wx.BITMAP_TYPE_ANY).ConvertToBitmap() ] self.statusbar = ESB.EnhancedStatusBar(self, -1) self.SetStatusBar(self.statusbar) self.statusbar.SetSize((-1, 28)) self.statusicon = wx.StaticBitmap(self.statusbar) self.statusicon.SetBitmap(self.statusicons[0]) self.ecmidl = wx.StaticText(self.statusbar) self.flashcountl = wx.StaticText(self.statusbar) self.dtccountl = wx.StaticText(self.statusbar) self.statusbar.SetFieldsCount(4) self.statusbar.SetStatusWidths([32, 170, 130, 110]) self.statusbar.AddWidget(self.statusicon, pos=0) self.statusbar.AddWidget(self.ecmidl, pos=1, horizontalalignment=ESB.ESB_ALIGN_LEFT) self.statusbar.AddWidget(self.flashcountl, pos=2, horizontalalignment=ESB.ESB_ALIGN_LEFT) self.statusbar.AddWidget(self.dtccountl, pos=3, horizontalalignment=ESB.ESB_ALIGN_LEFT) self.statusbar.SetStatusStyles( [wx.SB_SUNKEN, wx.SB_SUNKEN, wx.SB_SUNKEN, wx.SB_SUNKEN]) self.outerp = wx.Panel(self) self.adapterboxp = wx.Panel(self.outerp) self.adapterboxsizer = wx.StaticBoxSizer(wx.VERTICAL, self.adapterboxp, "FTDI Devices:") self.adapterboxp.SetSizer(self.adapterboxsizer) self.adapterlist = wx.Choice(self.adapterboxp, wx.ID_ANY, size=(-1, 32)) self.adapterboxsizer.Add(self.adapterlist, 1, wx.ALL | wx.EXPAND, border=10) self.labelbook = LB.LabelBook(self.outerp, agwStyle=LB.INB_FIT_LABELTEXT | LB.INB_LEFT | LB.INB_DRAW_SHADOW | LB.INB_GRADIENT_BACKGROUND) self.bookpages = {} maxdims = [0, 0] for a, d in self.apps.items(): enablestates = None if "enable" in self.apps[a]: enablestates = self.apps[a]["enable"] self.bookpages[a] = d["panel"](self, a, self.apps[a], enablestates) x, y = self.bookpages[a].GetSize() if x > maxdims[0]: maxdims[0] = x if y > maxdims[1]: maxdims[1] = y self.labelbook.AddPage(self.bookpages[a], d["label"], False) for k in self.bookpages.keys(): self.bookpages[k].SetMinSize(maxdims) self.modelp = wx.Panel(self.outerp, style=wx.BORDER_SUNKEN) self.modelbox = wx.BoxSizer(wx.VERTICAL) self.modell = wx.StaticText(self.modelp, label="", style=wx.ALIGN_CENTRE_HORIZONTAL | wx.ALIGN_CENTRE_VERTICAL) self.ecupnl = wx.StaticText(self.modelp, label="", style=wx.ALIGN_CENTRE_HORIZONTAL | wx.ALIGN_CENTRE_VERTICAL) font1 = self.GetFont().Bold() font2 = self.GetFont().Bold() font1.SetPointSize(font1.GetPointSize() * 1.25) font2.SetPointSize(font2.GetPointSize() * 2) self.modell.SetFont(font2) self.ecupnl.SetFont(font1) self.modelbox.AddSpacer(5) self.modelbox.Add(self.modell, 0, wx.CENTER) self.modelbox.Add(self.ecupnl, 0, wx.CENTER) self.modelbox.AddSpacer(5) self.modelp.SetSizer(self.modelbox) self.outersizer = wx.BoxSizer(wx.VERTICAL) self.outersizer.Add(self.adapterboxp, 0, wx.EXPAND | wx.ALL, 5) self.outersizer.Add(self.modelp, 0, wx.EXPAND | wx.ALL, 5) self.outersizer.Add(self.labelbook, 2, wx.EXPAND | wx.ALL, 5) self.outerp.SetSizer(self.outersizer) self.mainsizer = wx.BoxSizer(wx.VERTICAL) self.mainsizer.Add(self.outerp, 1, wx.EXPAND) self.mainsizer.SetSizeHints(self) self.SetSizer(self.mainsizer) self.adapterlist.Bind(wx.EVT_CHOICE, self.OnAdapterSelected) self.Bind(wx.EVT_CLOSE, self.OnClose) self.debuglog = HondaECU_LogPanel(self) dispatcher.connect(self.USBMonitorHandler, signal="USBMonitor", sender=dispatcher.Any) dispatcher.connect(self.AppPanelHandler, signal="AppPanel", sender=dispatcher.Any) dispatcher.connect(self.KlineWorkerHandler, signal="KlineWorker", sender=dispatcher.Any) self.usbmonitor = USBMonitor(self) self.klineworker = KlineWorker(self) self.Layout() self.Center() self.Show() self.usbmonitor.start() self.klineworker.start() self.powercycle = PowerCycleDialog(None) def __clear_data(self): self.ecuinfo = {} def __clear_widgets(self): self.ecmidl.SetLabel("") self.flashcountl.SetLabel("") self.dtccountl.SetLabel("") self.modell.SetLabel("") self.ecupnl.SetLabel("") self.statusicon.SetBitmap(self.statusicons[0]) self.statusbar.OnSize(None) def KlineWorkerHandler(self, info, value): if info in ["ecmid", "flashcount", "dtc", "dtccount", "state"]: self.ecuinfo[info] = value if info == "state": self.statusicon.SetToolTip( wx.ToolTip("state: %s" % (str(value).split(".")[-1]))) if value in [ECUSTATE.OFF, ECUSTATE.UNKNOWN]: #BLACK self.__clear_widgets() # self.statusicon.SetBitmap(self.statusicons[0]) elif value in [ECUSTATE.RECOVER_NEW, ECUSTATE.RECOVER_OLD]: #YELLOW self.statusicon.SetBitmap(self.statusicons[1]) elif value in [ECUSTATE.OK]: #GREEN self.statusicon.SetBitmap(self.statusicons[2]) elif value in [ECUSTATE.FLASH]: #BLUE self.statusicon.SetBitmap(self.statusicons[3]) elif value in [ECUSTATE.SECURE]: #PURPLE self.statusicon.SetBitmap(self.statusicons[4]) # elif value in [ECUSTATE.POSTWRITEx00,ECUSTATE.POSTWRITEx12]: #RED # self.statusicon.SetBitmap(self.statusicons[5]) elif info == "ecmid": if len(value) > 0: ecmid = " ".join(["%02x" % i for i in value]) self.ecmidl.SetLabel(" ECM ID: %s" % ecmid) if value in ECM_IDs: model = "%s (%s)" % (ECM_IDs[value]["model"], ECM_IDs[value]["year"]) pn = ECM_IDs[value]["pn"] else: model = "Unknown Model" pn = "-" for m in ECM_IDs.keys(): if m[:3] == value[:3]: model = "%s (%s)" % (ECM_IDs[m]["model"], ECM_IDs[m]["year"]) break self.modell.SetLabel(model) self.ecupnl.SetLabel(pn) self.Layout() elif info == "flashcount": if value >= 0: self.flashcountl.SetLabel(" Flash Count: %d" % value) elif info == "dtccount": if value >= 0: self.dtccountl.SetLabel(" DTC Count: %d" % value) self.statusbar.OnSize(None) elif info == "data": if not info in self.ecuinfo: self.ecuinfo[info] = {} self.ecuinfo[info][value[0]] = value[1:] def OnClose(self, event): with open(self.configfile, 'w') as configfile: self.config.write(configfile) self.run = False self.usbmonitor.join() self.klineworker.join() for w in wx.GetTopLevelWindows(): w.Destroy() def OnDetectMap(self, event): with wx.FileDialog(self, "Open ECU dump file", wildcard="ECU dump (*.bin)|*.bin", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return pathname = fileDialog.GetPath() ecupn = os.path.splitext(os.path.split(pathname)[-1])[0] for i in ECM_IDs.values(): if ecupn == i["pn"] and "keihinaddr" in i: fbin = open(pathname, "rb") nbyts = os.path.getsize(pathname) byts = bytearray(fbin.read(nbyts)) fbin.close() idadr = int(i["keihinaddr"], 16) wx.MessageDialog( None, "Map ID: " + byts[idadr:(idadr + 7)].decode("ascii"), "", wx.CENTRE | wx.STAY_ON_TOP).ShowModal() return wx.MessageDialog(None, "Map ID: unknown", "", wx.CENTRE | wx.STAY_ON_TOP).ShowModal() def OnBinChecksum(self, event): with wx.FileDialog(self, "Open ECU dump file", wildcard="ECU dump (*.bin)|*.bin", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return pathname = fileDialog.GetPath() fbin = open(pathname, "rb") nbyts = os.path.getsize(pathname) byts = bytearray(fbin.read(nbyts)) fbin.close() wx.MessageDialog( None, "Checksum: %s" % ("good" if checksum8bitHonda(byts) == 0 else "bad"), "", wx.CENTRE | wx.STAY_ON_TOP).ShowModal() return def OnDebug(self, event): self.debuglog.Show() def OnAppButtonClicked(self, event): b = event.GetEventObject() if not b.appid in self.appanels: enablestates = None if "enable" in self.apps[b.appid]: enablestates = self.apps[b.appid]["enable"] self.appanels[b.appid] = self.apps[b.appid]["panel"]( self, b.appid, self.apps[b.appid], enablestates) self.appbuttons[b.appid].Disable() self.appanels[b.appid].Raise() def USBMonitorHandler(self, action, device, config): dirty = False if action == "error": if platform.system() == "Windows": wx.MessageDialog( None, "libusb error: make sure libusbk is installed", "", wx.CENTRE | wx.STAY_ON_TOP).ShowModal() elif action == "add": if not device in self.ftdi_devices: self.ftdi_devices[device] = config dirty = True elif action == "remove": if device in self.ftdi_devices: if device == self.active_ftdi_device: dispatcher.send( signal="FTDIDevice", sender=self, action="deactivate", device=self.active_ftdi_device, config=self.ftdi_devices[self.active_ftdi_device]) self.active_ftdi_device = None self.__clear_data() del self.ftdi_devices[device] dirty = True if len(self.ftdi_devices) > 0: if not self.active_ftdi_device: self.active_ftdi_device = list(self.ftdi_devices.keys())[0] dispatcher.send( signal="FTDIDevice", sender=self, action="activate", device=self.active_ftdi_device, config=self.ftdi_devices[self.active_ftdi_device]) dirty = True else: pass if dirty: self.adapterlist.Clear() for device in self.ftdi_devices: cfg = self.ftdi_devices[device] self.adapterlist.Append( "Bus %03d Device %03d: %s %s %s" % (cfg.bus, cfg.address, usb.util.get_string(cfg, cfg.iManufacturer), usb.util.get_string(cfg, cfg.iProduct), usb.util.get_string(cfg, cfg.iSerialNumber))) if self.active_ftdi_device: self.adapterlist.SetSelection( list(self.ftdi_devices.keys()).index( self.active_ftdi_device)) def OnAdapterSelected(self, event): device = list( self.ftdi_devices.keys())[self.adapterlist.GetSelection()] if device != self.active_ftdi_device: if self.active_ftdi_device != None: dispatcher.send( signal="FTDIDevice", sender=self, action="deactivate", device=self.active_ftdi_device, config=self.ftdi_devices[self.active_ftdi_device]) self.__clear_data() self.active_ftdi_device = device dispatcher.send(signal="FTDIDevice", sender=self, action="activate", device=self.active_ftdi_device, config=self.ftdi_devices[self.active_ftdi_device]) def AppPanelHandler(self, appid, action): if action == "close": if appid in self.appanels: del self.appanels[appid] self.appbuttons[appid].Enable()