class ModeListFull(BaseGridW): markMode = QtCore.pyqtSignal(int, str, str, str) # mode_id, mark_id saveMode = QtCore.pyqtSignal(str, str) # author, comment outMsg = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(ModeListFull, self).__init__(parent) self.modes_db = ModesDB() self.filterw = ModeListFilter() self.grid.addWidget(self.filterw, 0, 0) self.update_modenum() self.filterw.set_nrows(100) self.filterw.ctrlsUpdate.connect(self.filter_cb) self.listw = ModeList(db=self.modes_db) self.grid.addWidget(self.listw, 1, 0) self.listw.modeSelected.connect(self.mode_sel_cb) self.ctrlw = ModeListBControls() self.grid.addWidget(self.ctrlw, 2, 0) self.save_blk = ModeListSaveBlock() self.grid.addWidget(self.save_blk, 3, 0) self.save_blk.saveMode.connect(self.saveMode) self.save_blk.outMsg.connect(self.outMsg) self.selected_mode = None def filter_cb(self, args): self.listw.update_modelist(**args) def mode_sel_cb(self, mode_id): if self.selected_mode is None and mode_id > 0: self.ctrlw.mark.connect(self.mark_cb) self.selected_mode = mode_id def mark_cb(self, mark): self.markMode.emit(self.selected_mode, mark, 'saver', 'automatic mode') def update_modenum(self): self.modes_db.execute("select count(id) from mode") m_num = self.modes_db.cur.fetchall()[0][0] self.filterw.set_maxrows(m_num) def update_modelist(self, update_marked=False): fvals = self.filterw.vals() if update_marked: fvals['update_marked'] = True self.listw.update_modelist(**fvals)
class ModeListCtrl(BaseGridW): markMode = QtCore.pyqtSignal(int, str, str, str) # mode_id, mark_id archiveMode = QtCore.pyqtSignal(int) # mode_id loadMode = QtCore.pyqtSignal(int) # mode_id saveMode = QtCore.pyqtSignal(str, str) # author, comment setZeros = QtCore.pyqtSignal() outMsg = QtCore.pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) self.modes_db = ModesDB() #filter controls self.grid_filter = QtWidgets.QGridLayout() self.grid.addLayout(self.grid_filter, 0, 0, 1, 1) self.grid_filter.addWidget(QtWidgets.QLabel("search"), 0, 0) self.filter_line = QtWidgets.QLineEdit() self.grid_filter.addWidget(self.filter_line, 0, 1, 1, 6) self.filter_line.editingFinished.connect(self.filter_cb) self.prev_b = QtWidgets.QPushButton("<<") self.grid_filter.addWidget(self.prev_b, 1, 0) self.prev_b.clicked.connect(self.prev_cb) self.nrows_box = PSpinBox() self.grid_filter.addWidget(self.nrows_box, 1, 1) self.nrows_box.done.connect(self.nrows_cb) self.grid_filter.addWidget(QtWidgets.QLabel("@"), 1, 2) self.startrow_box = PSpinBox() self.grid_filter.addWidget(self.startrow_box, 1, 3) self.startrow_box.done.connect(self.startrow_cb) self.grid_filter.addWidget(QtWidgets.QLabel("of"), 1, 4) self.maxrows_box = PSpinBox() self.grid_filter.addWidget(self.maxrows_box, 1, 5) self.maxrows_box.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) self.maxrows_box.setReadOnly(True) self.next_b = QtWidgets.QPushButton(">>") self.grid_filter.addWidget(self.next_b, 1, 6) self.next_b.clicked.connect(self.next_cb) # List self.listw = ModeList(db=self.modes_db) self.grid.addWidget(self.listw, 1, 0) self.listw.modeSelected.connect(self.mode_sel_cb) # Bottom controls self.grid_bottom = QtWidgets.QGridLayout() self.grid.addLayout(self.grid_bottom, 2, 0, 1, 1) self.grid_bottom.addWidget(QtWidgets.QLabel("mark"), 0, 0, 2, 1) self.buttons = [] self.marks = ['einj', 'eext', 'pinj', 'pext', 'e2v4', 'p2v4', 'e2v2', 'p2v2'] m_len = len(self.marks) rlen = 4 crow = 0 for ind in range(m_len): if ind == rlen: crow += 1 btn = QtWidgets.QPushButton(self.marks[ind]) btn.setStyleSheet("background-color: " + mode_colors[self.marks[ind]]) btn.setFixedWidth(100) self.grid_bottom.addWidget(btn, crow, ind - crow * rlen + 1) self.buttons.append(btn) btn.clicked.connect(self.mark_buttons_cb) hSpacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.grid_bottom.addItem(hSpacer, 0, rlen + 2) self.btn_archive = QtWidgets.QPushButton('Archive') self.grid_bottom.addWidget(self.btn_archive, 0, rlen + 3) self.btn_archive.setStyleSheet("background-color: red") self.btn_archive.setFixedWidth(110) self.btn_archive.clicked.connect(self.btn_archive_cb) self.btn_load = QtWidgets.QPushButton('Load') self.grid_bottom.addWidget(self.btn_load, 0, rlen + 4) self.btn_load.setFixedWidth(110) self.btn_load.clicked.connect(self.btn_load_cb) self.btn_zeros = QtWidgets.QPushButton('Zeros') self.grid_bottom.addWidget(self.btn_zeros, 1, rlen + 3) self.btn_zeros.setStyleSheet("background-color: yellow") self.btn_zeros.clicked.connect(self.setZeros) # Save Block self.grid_save = QtWidgets.QGridLayout() self.grid.addLayout(self.grid_save, 3, 0, 1, 1) self.grid_save.addWidget(QtWidgets.QLabel("Comment:"), 0, 0) self.grid_save.addWidget(QtWidgets.QLabel("author:"), 1, 0) self.comment_line = QtWidgets.QLineEdit() self.grid_save.addWidget(self.comment_line, 0, 1) self.author_line = QtWidgets.QLineEdit() self.grid_save.addWidget(self.author_line, 1, 1) self.btn_save = QtWidgets.QPushButton('save') self.grid_save.addWidget(self.btn_save, 0, 2, 2, 1) self.btn_save.clicked.connect(self.btn_save_cb) self.nrows, self.maxrows, self.startrow, self.filter = 100, 0, 0, None self.update_modenum() self.nrows_box.setValue(self.nrows) self.selected_mode = None # filter control functions def update_modelist(self, update_marked=False): args = { 'limit': self.nrows, 'offset': self.startrow, 'filter': self.filter, 'update_marked': update_marked } self.listw.update_modelist(**args) def update_modenum(self): self.modes_db.execute("select count(id) from mode") self.maxrows = self.modes_db.cur.fetchall()[0][0] self.maxrows_box.setValue(self.maxrows) def set_nrows(self, nrows): self.nrows = nrows self.nrows_box.setValue(self.nrows) def nrows_cb(self, nrows): if self.startrow + nrows > self.maxrows: self.nrows = self.maxrows - self.startrow self.nrows_box.setValue(self.nrows) else: self.nrows = nrows self.update_modelist() def startrow_cb(self, startrow): if self.nrows + startrow > self.maxrows: self.startrow = self.maxrows - self.nrows self.startrow_box.setValue(self.startrow) else: self.startrow = startrow self.update_modelist() def filter_cb(self): self.filter = self.filter_line.text() if self.filter == "": self.filter = None self.update_modelist() def prev_cb(self): if self.startrow - self.nrows >= 0: self.startrow -= self.nrows else: self.startrow = 0 self.startrow_box.setValue(self.startrow) self.update_modelist() def next_cb(self): if self.startrow + 2 * self.nrows < self.maxrows: self.startrow += self.nrows else: self.startrow = self.maxrows - self.nrows self.startrow_box.setValue(self.startrow) self.update_modelist() # mode list functions def mode_sel_cb(self, mode_id): self.selected_mode = mode_id # bottom control def mark_buttons_cb(self): if self.selected_mode is None: self.outMsg.emit('no mode selected') return ind = self.buttons.index(self.sender()) self.markMode.emit(self.selected_mode, self.marks[ind], 'saver', 'automatic mode') def btn_archive_cb(self): if self.selected_mode is None: self.outMsg.emit('no mode selected') return self.archiveMode.emit(self.selected_mode) def btn_load_cb(self): if self.selected_mode is None: self.outMsg.emit('no mode selected') return self.loadMode.emit(self.selected_mode) def btn_save_cb(self): comment = str2u(self.comment_line.text()) if len(comment) == 0: self.outMsg.emit('no comment - no save') return author = str2u(self.author_line.text()) if len(author) == 0: self.outMsg.emit('save: it isn`t polite to operate machine anonymously') return self.saveMode.emit(author, comment)
class ModeDaemon: def __init__(self): self.db = ModesDB() ans = self.db.mode_chans() self.db_chans = [list(c) for c in ans] cf = ChanFactory() # dict for faster id-based lookup self.cind = {x[2]: cf.create_chan(x[0], x[1]) for x in self.db_chans} self.name_ind = {x[1]: x[2] for x in self.db_chans} self.mode_ser = ModesServer( ) # message server for accelerator mode control self.mode_ser.load.connect(self.loadMode) self.mode_ser.save.connect(self.save_mode) self.mode_ser.loadMarked.connect(self.loadMarked) self.mode_ser.markMode.connect(self.markMode) self.mode_ser.walkerLoad.connect(self.walkerLoad) self.mode_ser.setZeros.connect(self.load_zeros) # create cache for "logical system" to "chan_name" self.sys_cache = SysCache(db=self.db) # load all current marks self.db.execute("SELECT name from modemark") marks = self.db.cur.fetchall() self.marks = [x[0] for x in marks] self.mode_caches = { x: ModeCache(x, db=self.db, sys_cache=self.sys_cache) for x in self.marks } # walkers for chain-load infrastructure self.walkers = { name: MagWalker(remag_srv + '.' + name) for name in remag_devs } for k in self.walkers: self.walkers[k].done.connect(self.mode_ser.walkerDone) def save_mode(self, author, comment): cind = self.cind data2json = { 'columns': ['fullchan_id', 'value', 'time', 'available'], 'doc_type': '1.0', 'data': { str(k): [cind[k].val, cind[k].time, cind[k].is_available()] for k in cind } } data_json = json.dumps(data2json, ignore_nan=True) mode_id = self.db.save_mode(author, comment, data_json) self.mode_ser.saved(mode_id) def check_syslist(self, syslist): if isinstance(syslist, list): if len(syslist) < 1: self.mode_ser.loaded('nothing requested to load') return False return True def applyMode(self, mode_data): # mode_data: {id:[value, ...]} loaded_count, nochange_count, na_count = 0, 0, 0 for c_id in mode_data: chan = self.cind.get(c_id, None) if chan is None: na_count += 1 print('unavaliable: ', c_id) continue # warning !!! it's not always correct if mode_data[c_id][0] == chan.val: nochange_count += 1 continue chan.setValue(mode_data[c_id][0]) loaded_count += 1 msg = 'loaded %d, nochange %d, unavailiable %d' % ( loaded_count, nochange_count, na_count) return msg def load_zeros(self, syslist, a_kinds): cids = self.sys_cache.cids(syslist, a_kinds) zero_mode = {x: [0.0] for x in cids} msg = self.applyMode(zero_mode) self.mode_ser.loaded(msg) def loadMode(self, mode_id, syslist, types): if not self.check_syslist(syslist) or not types: return data = self.db.load_mode(mode_id, syslist, types) msg = self.applyMode(data) self.mode_ser.loaded(msg) def loadMarked(self, mark, syslist, types): if not self.check_syslist(syslist) or not types: return data = self.mode_caches[mark].extract(syslist, types) msg = self.applyMode(data) self.mode_ser.markedLoaded(mark, msg) def markMode(self, mode_id, mark, comment, author): self.db.mark_mode(mode_id, mark, comment, author) self.mode_caches[mark] = ModeCache(mark, db=self.db, sys_cache=self.sys_cache) self.mode_ser.update() # currently it's a special load to cycle k500 magnets with drivers automatics def walkerLoad(self, walkers_path, coefs=None): # walkers_path - is a dict with {'walker': [marks] } # coefs - the same dictionary with coefs for values #print("walker load: ", walkers_path, coefs) for key in walkers_path: marks = walkers_path[key] if marks[0] is None: del marks[0] cname = remag_srv + '.' + key + '.Iset' # case ? c_id = self.name_ind[cname] vs = [] for m in marks: row = self.mode_caches[m].data[c_id] vs.append(row[0]) if coefs is not None: if coefs[key] is not None: for ind in range(len(vs)): vs[ind] *= coefs[key][ind] self.walkers[key].run_list(np.array(vs)) def dump_state(self): dump_file = open("/var/tmp/moded_dump", "w") for x in self.db_chans: dump_file.write(str(x) + "\n") dump_file.close()