def handleCommand(self, message): """handles command common for all detectors; returns False if command is unknown""" arg = None if len(message) > 1: arg = message[1].decode() command = message[0] if command == codes.ping: self.commandSocket.send(codes.ok) elif command == codes.pcaAsksForDetectorStatus: if self.configTag: self.commandSocket.send_multipart([ self.stateMachine.currentState.encode(), self.configTag.encode() ]) else: self.commandSocket.send_multipart( [self.stateMachine.currentState.encode()]) elif command == codes.detectorChangePartition: partition = partitionDataObject(json.loads(arg)) self.changePCA(partition) self.commandSocket.send(codes.ok) elif command == codes.check: self.commandSocket.send(codes.ok) partition = partitionDataObject(json.loads(arg)) if partition.id != self.pcaID: self.changePCA(partition) else: return False return True
def getPCAData(self): """get PCA Information from ECS""" requestSocket = self.context.socket(zmq.REQ) requestSocket.setsockopt(zmq.RCVTIMEO, self.receive_timeout) requestSocket.connect( "tcp://%s:%s" % (self.configFile['ECAAddress'], self.configFile['ECARequestPort'])) requestSocket.send_multipart( [codes.detectorAsksForPCA, self.MyId.encode()]) try: pcaDataJSON = requestSocket.recv() if pcaDataJSON == codes.idUnknown: sys.exit(1) pcaDataJSON = json.loads(pcaDataJSON.decode()) pcaData = partitionDataObject(pcaDataJSON) except zmq.Again: print("timeout getting pca Data") requestSocket.close() return None except zmq.error.ContextTerminated: requestSocket.close() finally: requestSocket.close() return pcaData
def getPCAData(): """get PCA Information from ECS""" config = configparser.ConfigParser() config.read("init.cfg") configFile = config["Default"] requestSocket = subContext.socket(zmq.REQ) requestSocket.connect( "tcp://%s:%s" % (configFile['ECAAddress'], configFile['ECARequestPort'])) requestSocket.send_multipart([codes.detectorAsksForPCA, detId.encode()]) try: pcaDataJSON = requestSocket.recv() if pcaDataJSON == codes.idUnknown: print("I have not been assigned to any partition :(") sys.exit(1) pcaDataJSON = json.loads(pcaDataJSON.decode()) pcaData = partitionDataObject(pcaDataJSON) except zmq.Again: print("timeout getting pca Data") requestSocket.close() return None except zmq.error.ContextTerminated: requestSocket.close() finally: requestSocket.close() return pcaData
def getPartition(self,id): """Get Partition with given id from Database; returns None if it does not exist""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (id,) try: res = c.execute("SELECT * FROM Partition WHERE id = ?", val).fetchone() if not res: return codes.idUnknown return partitionDataObject(res) except Exception as e: return self.handleError(e,"error getting partition") finally: connection.close()
def getPartitionForDetector(self,id): """gets the Partition of a Detector; returns DataObject or ErrorCode""" connection = sqlite3.connect(self.dataBaseFile) c = connection.cursor() val = (id,) try: res = c.execute("SELECT * FROM Partition WHERE Partition.id IN (SELECT PartitionId FROM (Mapping JOIN Partition ON Mapping.PartitionId = Partition.id) WHERE DetectorId = ?)", val).fetchone() if not res: return codes.idUnknown return partitionDataObject(res) except Exception as e: return self.handleError(e,"error getting partition for Detector") finally: connection.close()
def form_valid(self, form): if not form.is_valid(): return super().form_invalid(form) values = { "id": form.cleaned_data["id"], "address": form.cleaned_data["address"], "portPublish": form.cleaned_data["portPublish"], "portLog": form.cleaned_data["portLog"], "portUpdates": form.cleaned_data["portUpdates"], "portCurrentState": form.cleaned_data["portCurrentState"], "portCommand": form.cleaned_data["portCommand"], } obj = partitionDataObject(values) ret = eca.createPartition(obj) if ret == True: return super().form_valid(form) else: self.errorMessage = ret return super().form_invalid(form)
def handleCommand(self, message): """handles command common for all Global Systems; returns False if command is unknown""" command = message[0] pcaId = None if len(message) > 1: pcaId = message[1].decode() if command == codes.ping: self.commandSocket.send(codes.ok) elif command == codes.pcaAsksForDetectorStatus: pcaId = message[1].decode() if pcaId and pcaId in self.PCAs: if pcaId in self.pcaConfigTag: self.commandSocket.send_multipart([ self.StateMachineForPca[pcaId].currentState.encode(), self.pcaConfigTag[pcaId].encode() ]) else: self.commandSocket.send_multipart( [self.StateMachineForPca[pcaId].currentState.encode()]) elif command == codes.addPartition: data = partitionDataObject(json.loads(message[1].decode())) self.addPartition(data) self.commandSocket.send(codes.ok) elif command == codes.deletePartition: pcaId = message[1].decode() self.deletePartition(pcaId) self.commandSocket.send(codes.ok) elif command == codes.remapDetector: detectorId = message[2].decode() if message[1] == codes.removed: self.abortFunction(self.detectorMapping[detectorId]) del self.detectorMapping[detectorId] else: pcaId = message[1].decode() self.abortFunction(pcaId) if detectorId in self.detectorMapping: self.abortFunction(self.detectorMapping[detectorId]) self.detectorMapping[detectorId] = pcaId self.commandSocket.send(codes.ok) #transitions elif command.decode() == GlobalSystemTransitions.configure: conf = None if len(message) > 2: conf = configObject(json.loads(message[2].decode())) if self.isPCAinTransition[pcaId]: self.commandSocket.send(codes.busy) elif not self.StateMachineForPca[pcaId].checkIfPossible( GlobalSystemTransitions.configure) or not conf: self.commandSocket.send(codes.error) print("error") else: self.commandSocket.send(codes.ok) self.isPCAinTransition[pcaId] = True workThread = threading.Thread(name="worker", target=self.configure, args=(pcaId, conf)) workThread.start() elif command.decode() == GlobalSystemTransitions.abort: if pcaId and pcaId in self.PCAs: self.abortFunction(pcaId) self.commandSocket.send(codes.ok) else: self.commandSocket.send(codes.error) elif command.decode() == GlobalSystemTransitions.reset: self.reset(pcaId) self.commandSocket.send(codes.ok) else: #command unknown return False return True
db.deleteConfigTag("TestTag") exit(0) detectorCount = int(sys.argv[1]) #nodeList = ["pn02","pn04","pn06","pn07","pn08"] nodeList = ["pn30", "pn31", "pn32", "pn33", "pn34"] nodeCount = len(nodeList) detectorsPerNode = int(detectorCount / nodeCount) rest = detectorCount % nodeCount startNode = 4 startPort = 80000 startId = 50 pca = partitionDataObject( ["test", "pn35", 79000, 79001, 79002, 79003, 79004, 79005]) db.addPartition(pca) configList = ["testFLES", "testDCS", "testQA", "testTFC"] for i in nodeList: extra = 0 if rest > 0: extra = 1 rest -= 1 for j in range(startId, startId + detectorsPerNode + extra): det = detectorDataObject( [str(j), i, "DetectorA", startPort, startPort + 1]) db.saveConfig("config_%s" % det.id, det.id, '{"pam1":"v1","pam2":"v2"}') configList.append("config_%s" % det.id) startPort = startPort + 2 db.addDetector(det)
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()