def __init__(self): self.timer = None self.logger = None self.allowPulls = False self.shuttingDown = False self.fpstatus = FPSTATUS_READY self.batchslstatus = BATCHSL_IDLE self.pgPrinters = {} self.pgManCtl = {} self.pxManCtl = {} self.pgPrtMon = {} self.connected = {} self.printing = {} wx.Frame.__init__(self, None, title="Rep Rap Notebook", size=[NBWIDTH, NBHEIGHT]) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onTimer, self.timer) self.Bind(wx.EVT_CLOSE, self.onClose) self.settings = Settings(self, cmd_folder) self.history = History(self.settings) ico = wx.Icon(os.path.join(self.settings.cmdfolder, "images", "rrh.ico"), wx.BITMAP_TYPE_ICO) self.SetIcon(ico) self.httpServer = None self.images = Images(os.path.join(self.settings.cmdfolder, "images")) self.nbil = wx.ImageList(16, 16) self.nbilAttentionIdx = self.nbil.Add(self.images.pngAttention) self.nbilLoadedCleanIdx = self.nbil.Add(self.images.pngLoadedclean) self.nbilLoadedDirtyIdx = self.nbil.Add(self.images.pngLoadeddirty) self.nbilNotReadyIdx = self.nbil.Add(self.images.pngNotready) self.nbilReadyIdx = self.nbil.Add(self.images.pngReady) self.nbilReadyDirtyIdx = self.nbil.Add(self.images.pngReadydirty) self.nbilPrintingIdx = self.nbil.Add(self.images.pngPrinting) self.nbilPausedIdx = self.nbil.Add(self.images.pngPaused) self.nbilIdleIdx = self.nbil.Add(self.images.pngIdle) self.nbilNotReadyBSIdx = self.nbil.Add(self.images.pngNotreadybs) self.nbilReadyBSIdx = self.nbil.Add(self.images.pngReadybs) self.nbilReadyDirtyBSIdx = self.nbil.Add(self.images.pngReadydirtybs) self.nbilIdleBSIdx = self.nbil.Add(self.images.pngIdlebs) p = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) sizerBtns = wx.BoxSizer(wx.HORIZONTAL) self.nb = wx.Notebook(p, size=(NBWIDTH, NBHEIGHT), style=wx.NB_TOP) self.nb.SetBackgroundColour(bkgd) self.nb.AssignImageList(self.nbil) self.Show() self.logger = Logger(self.nb, self) self.logger.SetBackgroundColour(bkgd) self.pgGCodeRef = GCRef(self.nb, self, cmd_folder) self.pgGCodeRef.SetBackgroundColour(bkgd) self.pgConnMgr = ConnectionManagerPanel(self.nb, self) self.pgConnMgr.SetBackgroundColour(bkgd) self.pxLogger = 0 self.pxGCodeRef = 1 self.pxFilePrep = 2 self.pxConnMgr = 3 self.pgFilePrep = FilePrepare(self.nb, self, self.history) self.pgFilePrep.SetBackgroundColour(bkgd) self.nb.AddPage(self.logger, LOGGER_TAB_TEXT, imageId=-1) self.nb.AddPage(self.pgGCodeRef, GCREF_TAB_TEXT, imageId=-1) self.nb.AddPage(self.pgFilePrep, FILEPREP_TAB_TEXT, imageId=self.nbilIdleIdx) self.nb.AddPage(self.pgConnMgr, CONNMGR_TAB_TEXT, imageId=-1) sizer.AddSpacer((20,20)) sizer.Add(sizerBtns) sizer.AddSpacer((10,10)) sizer.Add(self.nb) p.SetSizer(sizer) self.nb.SetSelection(self.pxFilePrep) self.httpServer = RepRapServer(self, self.settings, self.logger) self.logger.LogMessage("Reprap host ready!") self.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.changePages) self.history.SetLogger(self.logger) self.timer.Start(MAINTIMER)
class MainFrame(wx.Frame): def __init__(self): self.timer = None self.logger = None self.allowPulls = False self.shuttingDown = False self.fpstatus = FPSTATUS_READY self.batchslstatus = BATCHSL_IDLE self.pgPrinters = {} self.pgManCtl = {} self.pxManCtl = {} self.pgPrtMon = {} self.connected = {} self.printing = {} wx.Frame.__init__(self, None, title="Rep Rap Notebook", size=[NBWIDTH, NBHEIGHT]) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onTimer, self.timer) self.Bind(wx.EVT_CLOSE, self.onClose) self.settings = Settings(self, cmd_folder) self.history = History(self.settings) ico = wx.Icon(os.path.join(self.settings.cmdfolder, "images", "rrh.ico"), wx.BITMAP_TYPE_ICO) self.SetIcon(ico) self.httpServer = None self.images = Images(os.path.join(self.settings.cmdfolder, "images")) self.nbil = wx.ImageList(16, 16) self.nbilAttentionIdx = self.nbil.Add(self.images.pngAttention) self.nbilLoadedCleanIdx = self.nbil.Add(self.images.pngLoadedclean) self.nbilLoadedDirtyIdx = self.nbil.Add(self.images.pngLoadeddirty) self.nbilNotReadyIdx = self.nbil.Add(self.images.pngNotready) self.nbilReadyIdx = self.nbil.Add(self.images.pngReady) self.nbilReadyDirtyIdx = self.nbil.Add(self.images.pngReadydirty) self.nbilPrintingIdx = self.nbil.Add(self.images.pngPrinting) self.nbilPausedIdx = self.nbil.Add(self.images.pngPaused) self.nbilIdleIdx = self.nbil.Add(self.images.pngIdle) self.nbilNotReadyBSIdx = self.nbil.Add(self.images.pngNotreadybs) self.nbilReadyBSIdx = self.nbil.Add(self.images.pngReadybs) self.nbilReadyDirtyBSIdx = self.nbil.Add(self.images.pngReadydirtybs) self.nbilIdleBSIdx = self.nbil.Add(self.images.pngIdlebs) p = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) sizerBtns = wx.BoxSizer(wx.HORIZONTAL) self.nb = wx.Notebook(p, size=(NBWIDTH, NBHEIGHT), style=wx.NB_TOP) self.nb.SetBackgroundColour(bkgd) self.nb.AssignImageList(self.nbil) self.Show() self.logger = Logger(self.nb, self) self.logger.SetBackgroundColour(bkgd) self.pgGCodeRef = GCRef(self.nb, self, cmd_folder) self.pgGCodeRef.SetBackgroundColour(bkgd) self.pgConnMgr = ConnectionManagerPanel(self.nb, self) self.pgConnMgr.SetBackgroundColour(bkgd) self.pxLogger = 0 self.pxGCodeRef = 1 self.pxFilePrep = 2 self.pxConnMgr = 3 self.pgFilePrep = FilePrepare(self.nb, self, self.history) self.pgFilePrep.SetBackgroundColour(bkgd) self.nb.AddPage(self.logger, LOGGER_TAB_TEXT, imageId=-1) self.nb.AddPage(self.pgGCodeRef, GCREF_TAB_TEXT, imageId=-1) self.nb.AddPage(self.pgFilePrep, FILEPREP_TAB_TEXT, imageId=self.nbilIdleIdx) self.nb.AddPage(self.pgConnMgr, CONNMGR_TAB_TEXT, imageId=-1) sizer.AddSpacer((20,20)) sizer.Add(sizerBtns) sizer.AddSpacer((10,10)) sizer.Add(self.nb) p.SetSizer(sizer) self.nb.SetSelection(self.pxFilePrep) self.httpServer = RepRapServer(self, self.settings, self.logger) self.logger.LogMessage("Reprap host ready!") self.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.changePages) self.history.SetLogger(self.logger) self.timer.Start(MAINTIMER) def changePages(self, evt): if self.shuttingDown: return sel = evt.GetSelection() oldSel = evt.GetOldSelection() for p in self.pxManCtl.keys(): if oldSel == self.pxManCtl[p]: self.pgManCtl[p].leavePage() if sel != self.pxLogger: self.logger.checkShowToaster() if sel == self.pxConnMgr: self.pgConnMgr.refreshPorts() elif sel == self.pxLogger: self.logger.hideToaster() def addPages(self, printer, reprap): mc = self.pgManCtl[printer] = ManualControl(self.nb, self, printer, reprap) mc.SetBackgroundColour(bkgd) pm = self.pgPrtMon[printer] = PrintMonitor(self.nb, self, printer, reprap, self.history) pm.SetBackgroundColour(bkgd) self.connected[printer] = True self.printing[printer] = False pm.setManCtl(mc) mc.setPrtMon(pm) mcText = MANCTL_TAB_TEXT % printer pmText = PRTMON_TAB_TEXT % printer self.pxManCtl[printer] = self.nb.GetPageCount() self.nb.AddPage(mc, mcText) self.nb.AddPage(pm, pmText, imageId=self.nbilNotReadyIdx) self.pgPrinters[printer] = (mcText, pmText) return (pm, mc) def delPages(self, printer): if printer not in self.pgPrinters.keys(): return del self.connected[printer] del self.printing[printer] self.pgManCtl[printer].leavePage() mcText, pmText = self.pgPrinters[printer] self.deletePageByTabText(mcText) self.deletePageByTabText(pmText) del self.pgPrinters[printer] del self.pgManCtl[printer] del self.pxManCtl[printer] del self.pgPrtMon[printer] def deletePageByTabText(self, text): pc = self.nb.GetPageCount() for i in range(pc): if text == self.nb.GetPageText(i): self.nb.RemovePage(i) return def findPMPageByPrinter(self, prtname): if prtname not in self.pgPrinters.keys(): return None text = self.pgPrinters[prtname][1] pc = self.nb.GetPageCount() for i in range(pc): if text == self.nb.GetPageText(i): return i return None def setPendantConnection(self, printer): if printer is None: print "clear pendant connection information" else: print "set pendant connection to printer (%s)" % printer def hiLiteLogTab(self, flag): if flag: self.nb.SetPageImage(self.pxLogger, self.nbilAttentionIdx) else: self.nb.SetPageImage(self.pxLogger, -1) def doPrinterError(self, printer): if self.nb.GetSelection() not in [ self.pxLogger, self.pxFilePrep ]: self.nb.SetSelection(self.pxFilePrep) self.pgConnMgr.disconnectByPrinter(printer) self.pgConnMgr.refreshPorts() def onLoggerPage(self): return self.nb.GetSelection() == self.pxLogger def replace(self, s, pm=None): d = {} d['%gcodebase%'] = "" d['%gcode%'] = "" if pm is not None: st, et = self.pm.getPrintTimes() if st is not None: d['%starttime%'] = time.strftime('%H:%M:%S', time.localtime(st)) if et is not None: d['%endtime%'] = time.strftime('%H:%M:%S', time.localtime(et)) if st is not None and et is not None: d['%elapsed%'] = formatElapsed(et - st) if self.pm.gcFile is not None: d['%gcodebase%'] = os.path.basename(self.pm.gcFile) d['%gcode%'] = self.pm.gcFile if 'configfile' in self.pgFilePrep.slicer.settings.keys(): d['%config%'] = self.pgFilePrep.slicer.settings['configfile'] else: d['%config%'] = "" d['%slicer%'] = self.pgFilePrep.settings.slicer if self.pgFilePrep.stlFile is not None: d['%stlbase%'] = os.path.basename(self.pgFilePrep.stlFile) d['%stl%'] = self.pgFilePrep.stlFile else: d['%stlbase%'] = "" d['%stl%'] = "" if self.pgFilePrep.gcFile is not None: d['%slicegcodebase%'] = os.path.basename(self.pgFilePrep.gcFile) d['%slicegcode%'] = self.pgFilePrep.gcFile else: d['%slicegcodebase%'] = "" d['%slicegcode%'] = "" for t in d.keys(): if d[t] is not None: s = s.replace(t, d[t]) s = s.replace('""', '') return s def updatePrintMonStatus(self, pname, status): pn = self.findPMPageByPrinter(pname) if pn is not None: if status == PMSTATUS_NOT_READY: self.nb.SetPageImage(pn, self.nbilNotReadyIdx) self.printing[pname] = False elif status == PMSTATUS_READY: self.nb.SetPageImage(pn, self.nbilReadyIdx) self.printing[pname] = False elif status == PMSTATUS_PRINTING: self.nb.SetPageImage(pn, self.nbilPrintingIdx) self.printing[pname] = True elif status == PMSTATUS_PAUSED: self.nb.SetPageImage(pn, self.nbilPausedIdx) self.printing[pname] = False else: self.nb.SetPageImage(pn, -1) self.printing[pname] = False def updateFilePrepStatus(self, status, batchstat): self.fpstatus = status self.batchslstatus = batchstat if status == FPSTATUS_READY: if batchstat == BATCHSL_IDLE: self.nb.SetPageImage(self.pxFilePrep, self.nbilReadyIdx) else: self.nb.SetPageImage(self.pxFilePrep, self.nbilReadyBSIdx) elif status == FPSTATUS_READY_DIRTY: if batchstat == BATCHSL_IDLE: self.nb.SetPageImage(self.pxFilePrep, self.nbilReadyDirtyIdx) else: self.nb.SetPageImage(self.pxFilePrep, self.nbilReadyDirtyBSIdx) elif status == FPSTATUS_BUSY: if batchstat == BATCHSL_IDLE: self.nb.SetPageImage(self.pxFilePrep, self.nbilNotReadyIdx) else: self.nb.SetPageImage(self.pxFilePrep, self.nbilNotReadyBSIdx) elif status == FPSTATUS_IDLE: if batchstat == BATCHSL_IDLE: self.nb.SetPageImage(self.pxFilePrep, self.nbilIdleIdx) else: self.nb.SetPageImage(self.pxFilePrep, self.nbilIdleBSIdx) else: self.nb.SetPageImage(self.pxFilePrep, -1) def isFilePrepModified(self, message): return self.pgFilePrep.checkModified(message=message) def getStatus(self): r = self.pgConnMgr.getStatus() r['fileprep'] = self.pgFilePrep.getStatus() return r def stopPrint(self, pname): if pname is None: if len(self.connected) >= 1: pname = self.connected.keys()[0] else: self.logger.LogMessage("No printer connected to stop") return else: if pname not in self.settings.printers and pname != 'all': self.logger.LogMessage("Unknown printer in stop print request") return if pname == 'all': for p in self.settings.printers: if p in self.connected.keys() and self.printing[p]: #pst = self.pgPrtMon[p].stopPrint() self.logger.LogMessage("We would have stopped printer %s here" % p) else: if pname in self.connected.keys() and self.printing[pname]: #return self.pgPrtMon[p].stopPrint() self.logger.LogMessage("We would have stopped printer %s here" % pname) else: self.logger.LogMessage("Printer %s not printing - skipping stop request" % pname) def setHeaters(self, pname, heaters): if pname is None: if len(self.connected) >= 1: pname = self.connected.keys()[0] else: self.logger.LogMessage("No printer connected to set heaters") return else: if pname not in self.settings.printers and pname != 'all': self.logger.LogMessage("Unknown printer in set heater request") return if pname == 'all': for p in self.settings.printers: if p in self.connected.keys(): self.pgManCtl[p].setHeaters(heaters) else: if pname in self.connected.keys(): self.pgManCtl[pname].setHeaters(heaters) else: self.logger.LogMessage("Printer %s not connected - skipping set heater request" % pname) def setSlicer(self, slicername, config): self.pgFilePrep.httpSetSlicer(slicername) if config is not None: self.pgFilePrep.httpCfgSlicer(config) def sliceFile(self, fn): self.pgFilePrep.httpSliceFile(fn) def getSlicer(self): return {'result': self.pgFilePrep.getSlicerConfigString()} def getTemps(self): return self.pgConnMgr.getTemps() def sendToFilePrep(self, fn): self.pgFilePrep.loadTempSTL(fn) def pullGCode(self, printmon, acceleration, retractiontime): self.pgFilePrep.pullGCode(printmon, acceleration, retractiontime) def currentPullStatus(self): return self.allowPulls def assertAllowPulls(self, flag): self.allowPulls = flag self.pgConnMgr.assertAllowPulls(flag) def onTimer(self, evt): self.pgConnMgr.tick() def onClose(self, evt): if self.checkPrinting(): return if not self.pgFilePrep.onClose(evt): self.nb.SetSelection(self.pxFilePrep) return for p in self.pgPrtMon.keys(): self.pgPrtMon[p].onClose(evt) for p in self.pgManCtl.keys(): self.pgManCtl[p].onClose(evt) self.pgConnMgr.onClose() if self.httpServer is not None: self.httpServer.close() if self.logger is not None: self.logger.close() self.shuttingDown = True self.settings.cleanUp() self.Destroy() def checkPrinting(self): if self.pgConnMgr.isAnyPrinting(): dlg = wx.MessageDialog(self, "Are you sure you want to exit while printing is active", 'Printing Active', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION) rc = dlg.ShowModal() dlg.Destroy() if rc != wx.ID_YES: return True return False def snapShot(self): return self.pgConnMgr.snapShot(block=False)