def connect_db(self, dbname=None, new=False): """connects to a db, possibly creating a new one""" if dbname is None: filelist = self.config.get_dblist() if new: filelist = None dlg = ConnectDialog(filelist=filelist) dlg.Raise() if dlg.ShowModal() == wx.ID_OK: dbname = dlg.filebrowser.GetValue() if not dbname.endswith('.ein'): dbname = "%s.ein" % dbname else: return None, dbname dlg.Destroy() db = InstrumentDB() if isInstrumentDB(dbname): db.connect(dbname) set_hostpid = True if not db.check_hostpid(): hostname = db.get_info('host_name') pid = db.get_info('process_id') ret = popup(None, FILE_IN_USE_MSG % (os.path.abspath(dbname), hostname, pid), 'Database in use', style=wx.YES_NO|wx.ICON_EXCLAMATION) set_hostpid = (ret != wx.ID_YES) if set_hostpid: db.set_hostpid() else: db.create_newdb(dbname, connect=True) self.config.set_current_db(dbname) return db, dbname
def onSavePosition(self, event=None): name = event.GetString().strip() if self.v_replace and name in self.config['positions']: ret = popup(self, "Overwrite Position %s?" %name, "Veriry Overwrite Position", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) if ret != wx.ID_YES: return imgfile = '%s.jpg' % time.strftime('%b%d_%H%M%S') fname = "%s/%s" % (self.imgdir, imgfile) self.waiting_for_imagefile = True self.save_image(fname=fname) tmp_pos = [] for v in self.config['stages'].values(): tmp_pos.append(float(self.motors[v['label']].VAL)) self.positions[name] = {'image': imgfile, 'timestamp': time.strftime('%b %d %H:%M:%S'), 'position': tmp_pos} if name not in self.pos_list.GetItems(): self.pos_list.Append(name) self.pos_name.Clear() self.pos_list.SetStringSelection(name) # auto-save file self.config['positions'] = self.positions self.autosave() self.write_htmllog(name) self.write_message("Saved Position '%s', image in %s" % (name, fname)) wx.CallAfter(Closure(self.onSelectPosition, event=None, name=name))
def onSaveScanDef(self, evt=None): dlg = wx.TextEntryDialog(self, "Scan Name:", "Enter Name for this Scan", "") dlg.SetValue(self.last_scanname) sname = None if dlg.ShowModal() == wx.ID_OK: sname = dlg.GetValue() dlg.Destroy() if sname is not None: scannames = [s.name for s in self.scandb.select('scandefs')] if sname in scannames: _ok = wx.ID_NO if self.scandb.get_info('scandefs_verify_overwrite', as_bool=True, default=1): _ok = popup(self, "Overwrite Scan Definition '%s'?" % sname, "Overwrite Scan Definition?", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) if (_ok == wx.ID_YES): print 'Deleting Scan Def ', sname self.scandb.del_scandef(sname) print 'Deleted Scan Def ', sname else: sname = '' if len(sname) > 0: name, scan = self.generate_scan(scanname=sname, force_save=True) thisscan = self.scandb.get_scandef(name) self.statusbar.SetStatusText("Saved scan '%s'" % sname) else: self.statusbar.SetStatusText("Could not overwrite scan '%s'" % sname) if len(sname) > 0: self.last_scanname = sname
def onSave(self, name): if len(name) < 1: return if name in self.positions and self.viewer.v_replace: ret = popup(self, "Overwrite Position %s?" % name, "Veriry Overwrite Position", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) if ret != wx.ID_YES: return imgfile = '%s.jpg' % time.strftime('%b%d_%H%M%S') imgfile = os.path.join(self.viewer.imgdir, imgfile) tmp_pos = self.viewer.ctrlpanel.read_position() imgdata, count = None, 0 if not os.path.exists(self.viewer.imgdir): os.makedirs(self.viewer.imgdir) while imgdata is None and count <100: imgdata = self.viewer.save_image(imgfile) if imgdata is None: time.sleep(0.5) count = count + 1 imgdata['source'] = 'SampleStage' imgdata['data_format'] = 'file' imgdata.pop('data') notes = json.dumps(imgdata) fullpath = os.path.join(os.getcwd(), imgfile) self.positions[name] = {'image': fullpath, 'timestamp': time.strftime('%b %d %H:%M:%S'), 'position': tmp_pos, 'notes': notes} if name not in self.pos_list.GetItems(): self.pos_list.Append(name) self.instdb.save_position(self.instname, name, tmp_pos, notes=notes, image=fullpath) self.pos_list.SetStringSelection(name) # auto-save file self.viewer.autosave(positions=self.positions) self.viewer.write_htmllog(name, self.positions[name]) imgfile_exists = False t0 = time.time() if not imgfile_exists and time.time()-t0 < 10: imgfile_exists = os.path.exists(fullpath) time.sleep(0.5) if imgfile_exists: self.viewer.write_message("Saved Position '%s', image in %s" % (name, imgfile)) else: self.viewer.write_message("COULD NOT SAVE IMAGE FILE!!") wx.CallAfter(Closure(self.onSelect, event=None, name=name))
def onClose(self, evt=None): ret = popup(self, "Really Quit?", "Exit Epics Scan?", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) if ret == wx.ID_YES: for child in self.subframes.values(): try: child.Destroy() except: pass self.Destroy()
def connect_db(self, dbname=None, new=False, server='sqlite', user='', password='', host='', port=None): """connects to a db, possibly creating a new one""" dlg = None # print("connect db top %.3f sec " % (time.time()-self.t0)) if dbname is None: filelist = self.config.get_dblist() if new: filelist = None dlg = ConnectDialog(filelist=filelist) dlg.Raise() if dlg.ShowModal() == wx.ID_OK: dbname = dlg.filebrowser.GetValue() if not dbname.endswith('.ein'): dbname = "%s.ein" % dbname else: # print(" ... Dlg Destroy") dlg.Destroy() return None, dbname db = InstrumentDB(dbname=dbname, server=server, user=user, password=password, host=host, port=port) # print("connect db %.3f sec " % (time.time()-self.t0)) # print(" Instruments: ", isInstrumentDB(dbname)) # for inst in db.get_all_instruments(): # print("## ", inst) if server=='sqlite': if isInstrumentDB(dbname): db.connect(dbname) set_hostpid = True if not db.check_hostpid(): hostname = db.get_info('host_name') pid = db.get_info('process_id') ret = popup(None, FILE_IN_USE_MSG % (os.path.abspath(dbname), hostname, pid), 'Database in use', style=wx.YES_NO|wx.ICON_EXCLAMATION) set_hostpid = (ret != wx.ID_YES) if set_hostpid: db.set_hostpid() else: db.create_newdb(dbname, connect=True) self.config.set_current_db(dbname) if dlg is not None: dlg.message.SetLabel("Connecting to Epics PVs in database") # print("connect to PVs ", len(db.get_allpvs())) for pv in db.get_allpvs(): self.pvlist.init_connect(pv.name) # , is_motor=(4==pv.pvtype_id)) # print(" --> ", len(self.pvlist.in_progress)) return db, dbname
def onClose(self, event=None): ret = popup(self, "Really Quit?", "Exit Sample Stage?", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) if ret == wx.ID_YES: finalize_epics() try: fout = open(WORKDIR_FILE, 'w') fout.write("%s\n" % os.path.abspath(os.curdir)) fout.close() except: pass self.Destroy()
def onClose(self, event=None): if wx.ID_YES == popup(self, "Really Quit?", "Exit Sample Stage?", style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION): fout = open(self.workdir_file, 'w') fout.write("%s\n" % os.path.abspath(os.curdir)) fout.close() self.imgpanel.Stop() try: self.overlay_frame.Destroy() except: pass self.Destroy()
def onClose(self, evt=None): ret = popup(self, "Really Quit?", "Exit Epics Scan?", style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if ret == wx.ID_YES: self.scantimer.Stop() for child in self.subframes.values(): try: child.onClose() except: pass self.Destroy()
def onErase(self, event): posname = self.pos_list.GetStringSelection() ipos = self.pos_list.GetSelection() if posname is None or len(posname) < 1: return if self.parent.v_erase: if wx.ID_YES != popup(self, "Erase %s?" % (posname), "Verify Erase", style=wx.YES_NO | wx.ICON_QUESTION): return self.instdb.remove_position(self.instname, posname) self.positions.pop(posname) self.pos_list.Delete(ipos) self.pos_name.Clear() self.parent.write_message("Erased Position %s" % posname)
def onErase(self, evt=None): posname = self.pos_list.GetStringSelection() verify = int(self.db.get_info("verify_erase")) if verify: ret = popup(self, "Erase position '%s'?" % (posname), "Verify Erase", style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return self.db.remove_position(posname, self.inst) ipos = self.pos_list.GetSelection() self.pos_list.Delete(ipos) self.write("Erased position '%s' for '%s'" % (posname, self.inst.name))
def onClose(self, event=None): ret = popup(self, "Really Quit?", "Exit Sample Stage?", style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if ret == wx.ID_YES: finalize_epics() try: fout = open(WORKDIR_FILE, 'w') fout.write("%s\n" % os.path.abspath(os.curdir)) fout.close() except: pass self.Destroy()
def onSave(self, name): if len(name) < 1: return if name in self.positions and self.parent.v_replace: ret = popup( self, "Overwrite Position %s?" % name, "Veriry Overwrite Position", style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION, ) if ret != wx.ID_YES: return imgfile = "%s.jpg" % time.strftime("%b%d_%H%M%S") imgfile = os.path.join(self.parent.imgdir, imgfile) tmp_pos = self.parent.ctrlpanel.read_position() imgdata, count = None, 0 while imgdata is None and count < 100: imgdata = self.parent.save_image(imgfile) if imgdata is None: time.sleep(0.5) count = count + 1 imgdata["source"] = "SampleStage" imgdata["data_format"] = "file" imgdata.pop("data") notes = json.dumps(imgdata) fullpath = os.path.join(os.getcwd(), imgfile) self.positions[name] = { "image": fullpath, "timestamp": time.strftime("%b %d %H:%M:%S"), "position": tmp_pos, "notes": notes, } if name not in self.pos_list.GetItems(): self.pos_list.Append(name) self.instdb.save_position(self.instname, name, tmp_pos, notes=notes, image=fullpath) self.pos_list.SetStringSelection(name) # auto-save file self.parent.autosave(positions=self.positions) self.parent.write_htmllog(name, self.positions[name]) self.parent.write_message("Saved Position '%s', image in %s" % (name, imgfile)) wx.CallAfter(Closure(self.onSelect, event=None, name=name))
def onErase(self, evt=None): posname = self.pos_list.GetStringSelection() verify = int(self.db.get_info('verify_erase')) if verify: ret = popup(self, "Erase position '%s'?" % (posname), 'Verify Erase', style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return self.db.remove_position(posname, self.inst) ipos = self.pos_list.GetSelection() self.pos_list.Delete(ipos) self.write("Erased position '%s' for '%s'" % (posname, self.inst.name))
def onErasePosition(self, event): posname = self.pos_list.GetStringSelection() ipos = self.pos_list.GetSelection() if posname is None or len(posname) < 1: return if self.v_erase: ret = popup(self, "Erase %s?" % (posname), 'Verify Erase', style=wx.YES_NO|wx.ICON_QUESTION) if ret != wx.ID_YES: return self.positions.pop(posname) self.pos_list.Delete(ipos) self.pos_name.Clear() self.display_imagefile(fname=None) self.write_message('Erased Position %s' % posname)
def onErasePosition(self, event): posname = self.pos_list.GetStringSelection() ipos = self.pos_list.GetSelection() if posname is None or len(posname) < 1: return if self.v_erase: ret = popup(self, "Erase %s?" % (posname), 'Verify Erase', style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return self.positions.pop(posname) self.pos_list.Delete(ipos) self.pos_name.Clear() self.display_imagefile(fname=None) self.write_message('Erased Position %s' % posname)
def onErase(self, event=None, posname=None, query=True): if posname is None: posname = self.pos_list.GetStringSelection() if posname is None or len(posname) < 1: return if self.viewer.v_erase and query: if wx.ID_YES != popup(self, "Erase %s?" % (posname), 'Verify Erase', style=wx.YES_NO|wx.ICON_QUESTION): return pos_names = self.pos_list.GetItems() ipos = pos_names.index(posname) self.instdb.remove_position(self.instname, posname) self.positions.pop(posname) self.pos_list.Delete(ipos) self.pos_name.Clear() self.viewer.write_message('Erased Position %s' % posname)
def onRemoveInstrument(self, event=None): inst = self.nb.GetCurrentPage().inst iname = inst.name MSG = "Permanently Remove Instrument '%s'?\nThis cannot be undone!" ret = popup(self, MSG % iname, 'Remove Instrument', style=wx.YES_NO|wx.ICON_QUESTION) if ret != wx.ID_YES: return self.db.remove_instrument(inst) self.db.commit() pages = {} for i in range(self.nb.GetPageCount()): pages[self.nb.GetPageText(i)] = i self.nb.DeletePage(pages[iname])
def onRemoveInstrument(self, event=None): inst = self.nb.GetCurrentPage().inst iname = inst.name MSG = "Permanently Remove Instrument '%s'?\nThis cannot be undone!" ret = popup(self, MSG % iname, 'Remove Instrument', style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return self.db.remove_instrument(inst) self.db.commit() pages = {} for i in range(self.nb.GetPageCount()): pages[self.nb.GetPageText(i)] = i self.nb.DeletePage(pages[iname])
def onGo(self, event): posname = self.pos_list.GetStringSelection() if posname is None or len(posname) < 1: return pos_vals = self.positions[posname]['position'] stage_names = self.config['stages'].values() postext = [] for name, val in zip(stage_names, pos_vals): postext.append(' %s\t= %.4f' % (name['label'], val)) postext = '\n'.join(postext) if self.v_move: ret = popup(self, "Move to %s?: \n%s" % (posname, postext), 'Verify Move', style=wx.YES_NO|wx.ICON_QUESTION) if ret != wx.ID_YES: return for name, val in zip(stage_names, pos_vals): self.motorwids[name['label']].drive.SetValue("%f" % val) self.write_message('moved to %s' % posname)
def onSavePosition(self, evt=None): posname = evt.GetString().strip() verify = int(self.db.get_info('verify_overwrite')) if verify and posname in self.pos_list.GetItems(): thispos = self.db.get_position(posname, self.inst) postext = ["\nSaved Values were:\n"] for pvpos in thispos.pvs: postext.append(' %s= %s' % (pvpos.pv.name, pvpos.value)) postext = '\n'.join(postext) ret = popup(self, "Overwrite %s?: \n%s" % (posname, postext), 'Verify Overwrite', style=wx.YES_NO|wx.ICON_QUESTION) if ret != wx.ID_YES: return self.save_current_position(posname) if posname not in self.pos_list.GetItems(): self.pos_list.Append(posname)
def connect_db(self, dbname=None, new=False): """connects to a db, possibly creating a new one""" dlg = None if dbname is None: filelist = self.config.get_dblist() if new: filelist = None dlg = ConnectDialog(filelist=filelist) dlg.Raise() if dlg.ShowModal() == wx.ID_OK: dbname = dlg.filebrowser.GetValue() if not dbname.endswith('.ein'): dbname = "%s.ein" % dbname else: print(" ... Dlg Destroy") dlg.Destroy() return None, dbname db = InstrumentDB() if isInstrumentDB(dbname): db.connect(dbname) set_hostpid = True if not db.check_hostpid(): hostname = db.get_info('host_name') pid = db.get_info('process_id') ret = popup(None, FILE_IN_USE_MSG % (os.path.abspath(dbname), hostname, pid), 'Database in use', style=wx.YES_NO|wx.ICON_EXCLAMATION) set_hostpid = (ret != wx.ID_YES) if set_hostpid: db.set_hostpid() else: db.create_newdb(dbname, connect=True) self.config.set_current_db(dbname) if dlg is not None: dlg.message.SetLabel("Connecting to Epics PVs in database") for pv in db.get_allpvs(): self.pvlist.init_connect(pv.name, is_motor=(4==pv.pvtype_id)) return db, dbname
def onGo(self, event): posname = self.pos_list.GetStringSelection() if posname is None or len(posname) < 1: return pos_vals = self.positions[posname]['position'] stage_names = self.config['stages'].values() postext = [] for name, val in zip(stage_names, pos_vals): postext.append(' %s\t= %.4f' % (name['label'], val)) postext = '\n'.join(postext) if self.v_move: ret = popup(self, "Move to %s?: \n%s" % (posname, postext), 'Verify Move', style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return for name, val in zip(stage_names, pos_vals): self.motorwids[name['label']].drive.SetValue("%f" % val) self.write_message('moved to %s' % posname)
def onSavePosition(self, evt=None): posname = evt.GetString().strip() verify = int(self.db.get_info('verify_overwrite')) if verify and posname in self.pos_list.GetItems(): thispos = self.db.get_position(posname, self.inst) postext = ["\nSaved Values were:\n"] for pvpos in thispos.pvs: postext.append(' %s= %s' % (pvpos.pv.name, pvpos.value)) postext = '\n'.join(postext) ret = popup(self, "Overwrite %s?: \n%s" % (posname, postext), 'Verify Overwrite', style=wx.YES_NO | wx.ICON_QUESTION) if ret != wx.ID_YES: return self.save_current_position(posname) if posname not in self.pos_list.GetItems(): self.pos_list.Append(posname)
def onGo(self, event): posname = self.pos_list.GetStringSelection() if posname is None or len(posname) < 1: return stages = self.viewer.config['stages'] posvals = self.positions[posname]['position'] postext = [] for pvname, value in posvals.items(): label = pvname desc = stages.get(pvname, {}).get('desc', None) if desc is not None: label = '%s (%s)' % (desc, pvname) postext.append(' %s\t= %.4f' % (label, float(value))) postext = '\n'.join(postext) if self.viewer.v_move: ret = popup(self, "Move to %s?: \n%s" % (posname, postext), 'Verify Move', style=wx.YES_NO|wx.ICON_QUESTION) if ret != wx.ID_YES: return for pvname, value in posvals.items(): caput(pvname, value) self.viewer.write_message('moved to %s' % posname)
def onGo(self, event): posname = self.pos_list.GetStringSelection() if posname is None or len(posname) < 1: return stages = self.parent.config["stages"] posvals = self.positions[posname]["position"] postext = [] for pvname, value in posvals.items(): label = pvname desc = stages.get(pvname, {}).get("desc", None) if desc is not None: label = "%s (%s)" % (desc, pvname) postext.append(" %s\t= %.4f" % (label, float(value))) postext = "\n".join(postext) if self.parent.v_move: ret = popup( self, "Move to %s?: \n%s" % (posname, postext), "Verify Move", style=wx.YES_NO | wx.ICON_QUESTION ) if ret != wx.ID_YES: return for pvname, value in posvals.items(): caput(pvname, value) self.parent.write_message("moved to %s" % posname)
def onSavePosition(self, event=None): name = event.GetString().strip() if self.v_replace and name in self.config['positions']: ret = popup(self, "Overwrite Position %s?" % name, "Veriry Overwrite Position", style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if ret != wx.ID_YES: return imgfile = '%s.jpg' % time.strftime('%b%d_%H%M%S') fname = "%s/%s" % (self.imgdir, imgfile) self.waiting_for_imagefile = True self.save_image(fname=fname) tmp_pos = [] for v in self.config['stages'].values(): tmp_pos.append(float(self.motors[v['label']].VAL)) self.positions[name] = { 'image': imgfile, 'timestamp': time.strftime('%b %d %H:%M:%S'), 'position': tmp_pos } if name not in self.pos_list.GetItems(): self.pos_list.Append(name) self.pos_name.Clear() self.pos_list.SetStringSelection(name) # auto-save file self.config['positions'] = self.positions self.autosave() self.write_htmllog(name) self.write_message("Saved Position '%s', image in %s" % (name, fname)) wx.CallAfter(Closure(self.onSelectPosition, event=None, name=name))
def onSaveScanDef(self, evt=None): dlg = wx.TextEntryDialog(self, "Scan Name:", "Enter Name for this Scan", "") dlg.SetValue(self.last_scanname) sname = None if dlg.ShowModal() == wx.ID_OK: sname = dlg.GetValue() dlg.Destroy() if sname is not None: scannames = [s.name for s in self.scandb.select('scandefs')] if sname in scannames: _ok = wx.ID_NO if self.scandb.get_info('scandefs_verify_overwrite', as_bool=True, default=1): _ok = popup(self, "Overwrite Scan Definition '%s'?" % sname, "Overwrite Scan Definition?", style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if (_ok == wx.ID_YES): self.scandb.del_scandef(sname) else: sname = '' if len(sname) > 0: name, scan = self.generate_scan(scanname=sname, force_save=True) thisscan = self.scandb.get_scandef(name) self.statusbar.SetStatusText("Saved scan '%s'" % sname) else: self.statusbar.SetStatusText("Could not overwrite scan '%s'" % sname) if len(sname) > 0: self.last_scanname = sname
def connect_db(self, dbname=None, new=False): """connects to a db, possibly creating a new one""" if dbname is None: filelist = self.config.get_dblist() if new: filelist = None dlg = ConnectDialog(filelist=filelist) dlg.Raise() if dlg.ShowModal() == wx.ID_OK: dbname = dlg.filebrowser.GetValue() if not dbname.endswith('.ein'): dbname = "%s.ein" % dbname else: return None, dbname dlg.Destroy() db = InstrumentDB() if isInstrumentDB(dbname): db.connect(dbname) set_hostpid = True if not db.check_hostpid(): hostname = db.get_info('host_name') pid = db.get_info('process_id') ret = popup(None, FILE_IN_USE_MSG % (os.path.abspath(dbname), hostname, pid), 'Database in use', style=wx.YES_NO | wx.ICON_EXCLAMATION) set_hostpid = (ret != wx.ID_YES) if set_hostpid: db.set_hostpid() else: db.create_newdb(dbname, connect=True) self.config.set_current_db(dbname) return db, dbname
def connect_db(self, dbname=None, new=False, server='sqlite', user='', password='', host='', port=None): """connects to a db, possibly creating a new one""" dlg = None # print("connect db top %.3f sec " % (time.time()-self.t0)) if dbname is None: filelist = self.config.get_dblist() if new: filelist = None dlg = ConnectDialog(filelist=filelist) dlg.Raise() if dlg.ShowModal() == wx.ID_OK: dbname = dlg.filebrowser.GetValue() if not dbname.endswith('.ein'): dbname = "%s.ein" % dbname else: # print(" ... Dlg Destroy") dlg.Destroy() return None, dbname db = InstrumentDB(dbname=dbname, server=server, user=user, password=password, host=host, port=port) # print("connect db %.3f sec " % (time.time()-self.t0)) # print(" Instruments: ", isInstrumentDB(dbname)) # for inst in db.get_all_instruments(): # print("## ", inst) if server == 'sqlite': if isInstrumentDB(dbname): db.connect(dbname) set_hostpid = True if not db.check_hostpid(): hostname = db.get_info('host_name') pid = db.get_info('process_id') ret = popup(None, FILE_IN_USE_MSG % (os.path.abspath(dbname), hostname, pid), 'Database in use', style=wx.YES_NO | wx.ICON_EXCLAMATION) set_hostpid = (ret != wx.ID_YES) if set_hostpid: db.set_hostpid() else: db.create_newdb(dbname, connect=True) self.config.set_current_db(dbname) if dlg is not None: dlg.message.SetLabel("Connecting to Epics PVs in database") # print("connect to PVs ", len(db.get_allpvs())) for pv in db.get_allpvs(): self.pvlist.init_connect(pv.name) # , is_motor=(4==pv.pvtype_id)) # print(" --> ", len(self.pvlist.in_progress)) return db, dbname