示例#1
0
	def validate_batch(self, seq):
		# Validate each command
		for seqRow in seq.iterrows():
			zone = seqRow[1]['zone']
			actuType = seqRow[1]['actuator_type']
			setVal = seqRow[1]['set_value']
			uuid = self.get_actuator_uuid(zone, actuType)
			name= self.get_actuator_name(zone, actuType)
			seqRow[1]['uuid'] = uuid
			seqRow[1]['name'] = name
			
			if not uuid in self.actuDict.keys():
				actuator = metaactuators.make_actuator(uuid, name, zone, actuType)
				if actuator == None:
					logging.error("Incorrect actuator type: %s", actuType)
					raise QRError('Incorrect actuator type', actuType)
				self.actuDict[uuid] = actuator
			actuator = self.actuDict[uuid]

			# Validation 1: Check input range
			if not actuator.validate_input(setVal):
				logging.error("Input value is not in correct range: %s", repr(seqRow[1]))
				raise QRError("Input value is not in correct range", seqRow[1])

			# Validation 2: Check if there is a dependent command in given batch
			for otherSeqRow in seq.iterrows():
				if seqRow[0]!=otherSeqRow[0]:
					if actuator.check_dependency(otherSeqRow[1], self.now()):
						logging.error("A command is dependent on a command in the given sequence: %s", repr(seqRow[1]) + repr(otherSeqRow[1]))
						raise QRError("A command is dependent on a command in the given sequence", repr(seqRow[1]) + repr(otherSeqRow[1]))
					elif otherSeqRow[1]['uuid'] == uuid:
						logging.error('A command has same target equipment with another: %s', repr(seqRow[1])+ repr(otherSeqRow[1]))
						raise QRError('A command has same target equipment with another', repr(seqRow[1])+ repr(otherSeqRow[1]))

			# Validation 3: Check if there is a dependent command in current status
			queryDep = {'set_time':{'$gte':self.now()-actuator.minLatency}}
			depCommands = self.statColl.load_dataframe(queryDep)
			for commRow in depCommands.iterrows():
				if actuator.check_dependency(commRow[1], self.now()):
					logging.error("A command is dependent on current status: %s", repr(seqRow[1])+repr(commRow[1]))
					raise QRError("A command is dependent on current status", repr(seqRow[1])+repr(commRow[1]))

			seq.loc[seqRow[0]] = seqRow[1]
示例#2
0
	def emergent_rollback(self):
		queryAll = {"under_control":True}
		resetQueue = self.statColl.load_dataframe(queryAll)
		resetQueue = resetQueue.sort(columns='set_time', axis='index')
		maxConcurrentResetNum = 10
		resetInterval = 10*60 # 10 minutes
		if len(resetQueue)==0:
			return None
		resetSeq= defaultdict(dict)
		#resetSeq = [[]]

		# Make actuators to reset and get earliest set time dependent on reset_queue
		earliestDepTime = self.dummyEndTime
		for row in resetQueue.iterrows():
			uuid = row[1]['uuid']
			name = row[1]['name']
			actuType = row[1]['actuator_type']
			if not uuid in self.actuDict.keys():
				actuator = metaactuators.make_actuator(uuid,name,actuType=actuType)
				if actuator == None:
					#raise QRError('Incorrect actuator type', actuType)
					print("Incorrect actuator type: ", actuType)
					continue
				self.actuDict[uuid] = actuator
			setTime = row[1]['set_time']
			dependentTime = setTime - actuator.get_longest_dependency()
			if earliestDepTime > dependentTime:
				earliestDepTime = dependentTime

		# Construct Reset Sequence
		# Filter redundant controls and align with dependency
		for row in resetQueue.iterrows():
			uuid = row[1]['uuid']
			inQFlag = False
			for l in resetSeq.values():
				if uuid in l.keys():
					inQFlag = True
			if inQFlag == True:
				continue
			actuator = self.actuDict[uuid]
			lastKey = 0
			now = self.now()
			row[1]['original_value'] = actuator.get_value(now-timedelta(hours=1), now).tail(1)[0]
			insertedFlag = False
			for k,l in resetSeq.iteritems():
				depList = actuator.get_dependent_actu_list()
				if not bool(set(depList) & set(l.keys())) and len(l)<maxConcurrentResetNum:
					resetSeq[k][uuid] = row[1].to_dict()
					insertedFlag = True
				lastKey = k
			lastKey += 1
			if not insertedFlag:
				resetSeq[lastKey][uuid] = row[1].to_dict()

		for key, stats in resetSeq.iteritems():
			oneResetSeq = pd.DataFrame()
			for uuid, stat in stats.iteritems():
				oneResetSeq = pd.concat([oneResetSeq, pd.DataFrame(stat, index=[0])])
			resetSeq[key] = oneResetSeq

#TODO: need to add checking acknowledgement
		# Rollback
		for k, l in resetSeq.iteritems():
			for key, stat in l.iterrows():
		#		stat = row[1]
				uuid = stat['uuid']
				name = stat['name']
				actuType = stat['actuator_type']
				if actuType in [self.actuNames.commonSetpoint]:
					setVal = stat['reset_value']
				else:
					setVal = -1
				
				actuator = self.actuDict[uuid]
				now = self.now()
				origVal = stat['original_value']
				setTime = self.now()
				expLogRow = ExpLogRow(uuid, name, setTime=setTime, setVal=setVal, origVal=origVal)
				actuator.reset_value(setVal, setTime)
			self.ack_issue(l)
			time.sleep(resetInterval)