def getAllUnmappedDetectors(self): """gets all Detectors which are currently unmmaped""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: res = c.execute("SELECT * FROM Detector Where Detector.id not in (select DetectorId From Mapping)").fetchall() return DataObjectCollection(res,detectorDataObject) except Exception as e: return self.handleError(e,"error getting unmapped detectors") finally: connection.close()
def getAllDetectors(self): """Get All Detectors in Detector Table; returns empty DataObjectCollection if there are now Detectors""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: c.execute("SELECT * FROM Detector") res = c.fetchall() return DataObjectCollection(res,detectorDataObject) except Exception as e: return self.handleError(e,"error getting detectors") finally: connection.close()
def getDetectorMapping(self): """get entire PCA Detector Mapping Table""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: c.execute("SELECT * From Mapping") res = c.fetchall() return DataObjectCollection(res, mappingDataObject) except Exception as e: return self.handleError(e,"error getting Mapping Table") finally: connection.close()
def getAllGlobalSystems(self): """get all global systems""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: c.execute("SELECT * FROM GlobalSystems") res = c.fetchall() return DataObjectCollection(res,globalSystemDataObject) except Exception as e: return self.handleError(e,"error getting Global Systems") finally: connection.close()
def getAllPartitions(self): """Get All Detectors in Detector Table""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: c.execute("SELECT * FROM Partition") res = c.fetchall() return DataObjectCollection(res, partitionDataObject) except Exception as e: return self.handleError(e,"error getting partitions") finally: connection.close()
def getCustomConfig(self,configList): """get Configs for a list of ConfigIds""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() try: res =c.execute("SELECT * from Configurations where Configurations.configId in (%s)" % " ,".join(list(map(lambda x:"?",configList))),configList).fetchall() #parameters(res[2]) are stored as a json string in the database res = list(map(lambda x:x[:2]+(json.loads(x[2]),),res)) return DataObjectCollection(res, configObject) except Exception as e: return self.handleError(e,"error getting All Costum Configurations") finally: connection.close()
def getDetectorsForPartition(self,pcaId): """get all Mapped Detectors for a given PCA Id""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (pcaId,) try: c.execute("SELECT * From Detector WHERE Detector.id in (SELECT d.id FROM Detector d JOIN Mapping m ON d.id = m.DetectorId WHERE PartitionId=?)",val) res = c.fetchall() return DataObjectCollection(res, detectorDataObject) except Exception as e: return self.handleError(e,"error getting detectors for Partition") finally: connection.close()
def getConfigsForManySystems(self,systemList): """get all possible Configurations for a List of Systems""" connection = sqlite3.connect("ECS_database.db") c = connection.cursor() try: res =c.execute("SELECT * from Configurations where systemId in (%s)" % " ,".join(list(map(lambda x:"?",systemList))),systemList).fetchall() if not res: return codes.idUnknown #load json from parameters string res = list(map(lambda x:x[:2]+(json.loads(x[2]),),res)) return DataObjectCollection(res, configObject) except Exception as e: return self.handleError(e,"error getting Configurations") finally: connection.close()
def getConfigsForSystem(self,systemId): """get all possible Configurations for a System""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (systemId,) try: res =c.execute("SELECT * FROM Configurations WHERE systemId=?",val).fetchall() if not res: return codes.idUnknown #load json from parameters string res = list(map(lambda x:x[:2]+(json.loads(x[2]),),res)) return DataObjectCollection(res, configObject) except Exception as e: return self.handleError(e,"error getting configurations for %s" % systemId) finally: connection.close()
def getConfigsForTag(self,tag): """get the subsystem configurations for a tag""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (tag,) try: res = c.execute("SELECT Configurations.configId,Configurations.systemId,parameters FROM Configurations join ConfigurationTag on Configurations.configId = ConfigurationTag.configId where tagname = ?",val).fetchall() if not res or len(res) == 0: return codes.idUnknown #load json from parameters string res = list(map(lambda x:x[:2]+(json.loads(x[2]),),res)) return DataObjectCollection(res, configObject) except Exception as e: return self.handleError(e,"error getting configurations for tag %s" % tag) finally: connection.close()
def getConfigsForPCA(self,pcaId): """get all possible Configs for Partition Systems""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (pcaId,) try: res =c.execute("""SELECT configid,detectorid,parameters FROM ((Partition Join Mapping on Partition.id = Mapping.PartitionId) join Detector on detectorId=Detector.id) left join Configurations on detectorid = Configurations.systemId Where Partitionid=? union select configid,id,parameters FROM GlobalSystems left join Configurations on GlobalSystems.id = Configurations.systemId """.replace("\n",""),val).fetchall() if not res: return codes.idUnknown #parameters(res[2]) are stored as a json string in the database; there could be no config for a system res = list(map(lambda x:x[:2]+(json.loads(x[2]),) if x[2] != None else x ,res)) return DataObjectCollection(res, configObject) except Exception as e: return self.handleError(e,"error getting Configurations for %s" % pcaId) finally: connection.close()
def __init__(self, type, startState="Unconfigured", configTag=None): config = configparser.ConfigParser() config.read("init.cfg") self.conf = config["Default"] self.receive_timeout = int(self.conf['receive_timeout']) mapping = None #ask ECS For required Data while mapping == None: try: requestSocket = zmq.Context().socket(zmq.REQ) requestSocket.connect( "tcp://%s:%s" % (self.conf['ECAAddress'], self.conf['ECARequestPort'])) requestSocket.setsockopt(zmq.RCVTIMEO, self.receive_timeout) requestSocket.send_multipart([codes.getAllPCAs]) partitions = requestSocket.recv() partitions = DataObjectCollection( json.loads(partitions.decode()), partitionDataObject) requestSocket.send_multipart( [codes.GlobalSystemAsksForInfo, type.encode()]) globalSystemInfo = requestSocket.recv() globalSystemInfo = globalSystemDataObject( json.loads(globalSystemInfo.decode())) requestSocket.send_multipart([codes.getDetectorMapping]) mapping = requestSocket.recv() mapping = DataObjectCollection(json.loads(mapping.decode()), mappingDataObject) except zmq.Again: print("timeout getting %s Data" % type) continue except zmq.error.ContextTerminated: pass finally: requestSocket.close() super().__init__(globalSystemInfo.id, globalSystemInfo.portCommand) #holds information which detector belongs to which Partition self.detectorMapping = {} for m in mapping: self.detectorMapping[m.detectorId] = m.partitionId self.MyId = globalSystemInfo.id #init data structures and configs configDet = configparser.ConfigParser() configDet.read("subsystem.cfg") configDet = configDet[type] self.StateMachineFile = configDet["stateFile"] self.StateMachineForPca = {} self.PCAs = {} self.isPCAinTransition = {} self.pcaConfigTag = {} self.pcaConfig = {} self.pcaSequenceNumber = {} self.pcaStatemachineLock = {} for p in partitions: self.PCAs[p.id] = p self.StateMachineForPca[p.id] = Statemachine( self.StateMachineFile, startState) if configTag: self.pcaConfigTag[p.id] = configTag self.isPCAinTransition[p.id] = False self.pcaSequenceNumber[p.id] = 0 self.pcaStatemachineLock[p.id] = threading.Lock() #send first update to All PCAs self.sendUpdateToAll() #start threads self.commandThread = threading.Thread(name="waitForCommands", target=self.waitForCommands) self.commandThread.start() self.pipeThread = threading.Thread(name="waitForPipeMessages", target=self.waitForPipeMessages) self.pipeThread.start()
def configure(self, arg=None): """perform a configure step""" if self.partitionLocked: self.log("Can't configure because Partition is locked") return codes.error if arg: arg = json.loads(arg) if arg["autoConfigure"] == "true": self.autoConfigure = True else: self.autoConfigure = False systemConfig = DataObjectCollection( json.loads(arg["systemConfig"]), configObject) lowest_in_hierarchie = None #set the new configurations find lowest system in the configuration hierarchie for conf in systemConfig: if conf.systemId in self.detectors: sys = self.detectors[conf.systemId] name = "Detectors" elif conf.systemId in self.globalSystems: sys = self.globalSystems[conf.systemId] name = conf.systemId else: self.log( "System %s is in received Config but is not in this partition", True) continue currentStateObject = sys.getStateObject() oldconfigTag = currentStateObject.configTag sys.setSystemConfig(conf) if oldconfigTag != conf.configId or currentStateObject.state == MappedStates.Unconfigured: sys.needsReconfiguring = True if lowest_in_hierarchie == None: lowest_in_hierarchie = name elif pcaStates.isLowerInHierarchie(name, lowest_in_hierarchie): lowest_in_hierarchie = name else: sys.needsReconfiguring = False if conf.systemId in self.detectors: self.configuringDetectors[conf.systemId] = False self.readyDetectors[conf.systemId] = True if lowest_in_hierarchie == None: self.log("nothing to be done for provided configuration list") return codes.ok #all systems above lowest system need to be reconfigured reconfigureList = pcaStates.systemsHigherInHierachie( lowest_in_hierarchie) for sys in reconfigureList: if sys == "Detectors": for id in self.detectors.keyIterator(): d = self.detectors[id] self.configuringDetectors[id] = True self.readyDetectors[id] = False d.needsReconfiguring = True else: gs = self.globalSystems[sys] gs.needsReconfiguring = True self.globalTag = arg["globalTag"] if self.stateMachine.currentState == PCAStates.Recording: for id in self.detectors.keyIterator(): d = self.detectors[id] if d.getMappedState() != MappedStates.Active: d.getReady(globalTag) return ECSCodes.ok function = self.configureFunctionForSystem[lowest_in_hierarchie] if function(): return codes.ok return codes.error
def checkConsistencyRequest(detectorList): #currently unused detectorList = DataObjectCollection(json.loads(detectorList), detectorDataObject) start_new_thread(self.checkSystemConsistency, (detectorList, )) return codes.ok
def __init__(self, id): self.id = id #for time measurement of configuring all Systems self.start_time = 0.0 self.end_time = 0.0 self.detector_configure_time_start = 0.0 #create lock try: self.lock = zc.lockfile.LockFile('/tmp/lock' + self.id, content_template='{pid}') except zc.lockfile.LockError: print("other Process is already Running " + self.id) exit(1) self.terminate = threading.Event() self.initdone = threading.Event() #handle SIGTERM signal signal.signal(signal.SIGTERM, self.terminatePCA) #read config File config = configparser.ConfigParser() config.read("init.cfg") conf = config["Default"] self.context = zmq.Context() self.receive_timeout = int(conf['receive_timeout']) self.ECSAdress = conf['ECAAddress'] self.ECARequestPort = conf['ECARequestPort'] def checkConsistencyRequest(detectorList): #currently unused detectorList = DataObjectCollection(json.loads(detectorList), detectorDataObject) start_new_thread(self.checkSystemConsistency, (detectorList, )) return codes.ok def measureConfigureTime(arg=None): """just for timemeasure purpose use self.configure instead""" self.start_time = time.time() return self.configure(arg) #lookup table for recieved commands self.functionForCodeDictionary = { #codes.getReady: self.configure, codes.getReady: measureConfigureTime, codes.start: self.startRecording, codes.stop: self.stopRecording, codes.removeDetector: self.removeDetector, codes.addDetector: self.addDetector, codes.abort: self.abort, codes.check: checkConsistencyRequest, codes.lock: self.lockPartition, codes.unlock: self.unlockPartition, codes.reset: self.resetSystem, codes.subsystemMessage: self.handleSystemMessage } #get your config configECS = None while configECS == None: requestSocket = self.context.socket(zmq.REQ) requestSocket.connect("tcp://%s:%s" % (conf['ECAAddress'], conf['ECARequestPort'])) requestSocket.setsockopt(zmq.RCVTIMEO, int(conf['receive_timeout'])) requestSocket.setsockopt(zmq.LINGER, 0) requestSocket.send_multipart([codes.pcaAsksForConfig, id.encode()]) try: #returns None in pca is unknown configJSON = requestSocket.recv() if configJSON == codes.idUnknown: print("id %s is not in Database" % self.id) sys.exit(1) configJSON = json.loads(configJSON.decode()) configECS = partitionDataObject(configJSON) except zmq.Again: print("timeout getting configuration") continue except zmq.error.ContextTerminated: pass finally: requestSocket.close() #init stuff self.detectors = MapWrapper() #update number self.sequence = 0 self.transitionNumber = 0 #the only one who may change the status Map, is the publisher thread self.statusMap = MapWrapper() self.sem = threading.Semaphore() self.publishQueue = Queue() self.autoConfigure = False self.globalTag = False self.partitionLocked = False #ZMQ Socket to publish new state Updates self.socketPublish = self.context.socket(zmq.PUB) self.socketPublish.bind("tcp://*:%s" % configECS.portPublish) #publish logmessages self.socketLogPublish = self.context.socket(zmq.PUB) self.socketLogPublish.bind("tcp://*:%s" % configECS.portLog) #Socket to wait for Updates From Detectors self.socketDetectorUpdates = self.context.socket(zmq.REP) self.socketDetectorUpdates.bind("tcp://*:%s" % configECS.portUpdates) #Socket to serve current statusMap self.socketServeCurrentStatus = self.context.socket(zmq.ROUTER) self.socketServeCurrentStatus.bind("tcp://*:%s" % configECS.portCurrentState) #socket for receiving commands self.remoteCommandSocket = self.context.socket(zmq.REP) self.remoteCommandSocket.bind("tcp://*:%s" % configECS.portCommand) #init logger self.logfile = conf["logPath"] debugMode = bool(conf["debugMode"]) logging.basicConfig( format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', #level = logging.DEBUG, handlers=[ #logging to file logging.FileHandler(self.logfile), #logging on console and WebUI logging.StreamHandler() ]) logging.getLogger().setLevel(logging.INFO) logging.getLogger().handlers[0].setLevel(logging.INFO) #set console log to info level if in debug mode if debugMode: logging.getLogger().handlers[1].setLevel(logging.INFO) else: logging.getLogger().handlers[1].setLevel(logging.CRITICAL) #get your Detectorlist detList = None while detList == None: requestSocket = self.context.socket(zmq.REQ) requestSocket.connect("tcp://%s:%s" % (conf['ECAAddress'], conf['ECARequestPort'])) requestSocket.setsockopt(zmq.RCVTIMEO, int(conf['receive_timeout'])) requestSocket.setsockopt(zmq.LINGER, 0) requestSocket.send_multipart( [codes.pcaAsksForDetectorList, self.id.encode()]) try: #receive detectors as json ret = requestSocket.recv() if ret == codes.error: self.log("received error getting DetectorList", True) continue detJSON = json.loads(ret.decode()) #create DataObjectCollection from JSON detList = DataObjectCollection(detJSON, detectorDataObject) except zmq.Again: self.log("timeout getting DetectorList", True) continue except zmq.error.ContextTerminated: pass finally: requestSocket.close() self.stateMachine = Statemachine(conf["stateMachineCSV"], PCAStates.Idle) #helper maps to determine global state self.readyDetectors = {} self.configuringDetectors = {} start_new_thread(self.publisher, ()) #Subscribers need some time to subscribe time.sleep(1) #tell subscribers to reset their state Table self.publishQueue.put((self.id, codes.reset)) #create global System objects systemList = ["TFC", "DCS", "QA", "FLES"] res = [] self.messageHandlerFunctionForSystem = { "DCS": self.handleDCSMessage, } #get info from ECS for s in systemList: requestSocket = self.context.socket(zmq.REQ) requestSocket.connect("tcp://%s:%s" % (conf['ECAAddress'], conf['ECARequestPort'])) requestSocket.setsockopt(zmq.RCVTIMEO, int(conf['receive_timeout'])) requestSocket.setsockopt(zmq.LINGER, 0) requestSocket.send_multipart( [codes.GlobalSystemAsksForInfo, s.encode()]) try: #receive detectors as json ret = requestSocket.recv() if ret == codes.error: self.log("received error getting GlobalSystem %s" % s, True) exit(1) if ret == codes.idUnknown: self.log("ECS does not know GlobalSystem %s" % s, True) exit(1) JSON = json.loads(ret.decode()) #create DataObjectCollection from JSON res.append(globalSystemDataObject(JSON)) except zmq.Again: self.log("timeout getting GlobalSystem %s" % s, True) exit(1) except zmq.error.ContextTerminated: pass finally: requestSocket.close() #create Objects tfcData, dcsData, qaData, flesData = res self.globalSystems = {} self.TFC = TFC(self.id, tfcData.address, tfcData.portCommand, "TFC", self.log, self.globalSystemTimeout, self.globalSystemReconnect) self.globalSystems["TFC"] = self.TFC self.DCS = DCS(self.id, dcsData.address, dcsData.portCommand, "DCS", self.log, self.globalSystemTimeout, self.globalSystemReconnect) self.globalSystems["DCS"] = self.DCS self.QA = QA(self.id, qaData.address, qaData.portCommand, "QA", self.log, self.globalSystemTimeout, self.globalSystemReconnect) self.globalSystems["QA"] = self.QA self.FLES = FLES(self.id, flesData.address, flesData.portCommand, "FLES", self.log, self.globalSystemTimeout, self.globalSystemReconnect) self.globalSystems["FLES"] = self.FLES #maps configure Functions to their corresponding PCA State self.configureFunctionForState = { PCAStates.Idle: self.TFC.getReady, PCAStates.TFC_Active: self.makeDetectorsReady, PCAStates.Detectors_Active: self.configureDCSandFLES, PCAStates.FLES_and_DCS_Active: self.QA.getReady, } self.configureFunctionForSystem = { "TFC": self.TFC.getReady, "Detectors": self.makeDetectorsReady, "DCS": self.configureDCSandFLES, "FLES": self.configureDCSandFLES, "QA": self.QA.getReady, } #create Detector objects threadArray = [] for d in detList: #in case there of a connection problem, creating a Detector might take a long time, therefore create a own thread for each detector t = threading.Thread(name='dcreate' + str(d.id), target=self.addDetector, args=(d, )) threadArray.append(t) t.start() for t in threadArray: t.join() self.publishQueue.put( (self.id, stateObject([ self.stateMachine.currentState, self.stateMachine.currentState, self.globalTag, None ]))) #thread stuff start_new_thread(self.waitForUpdates, ()) start_new_thread(self.waitForStateTableRequests, ()) start_new_thread(self.waitForCommands, ()) self.initdone.set()