def executeRule(self, rule):
		actionManager = ActionManager()
		action, originalModel, parameters = actionManager.getActionAndTemplateAndParameterValues(rule.consequent)

		parameters.update({'buildingName' : rule.buildingName})
		if rule.roomName: parameters.update({'roomName' : rule.roomName})
		if rule.groupId: parameters.update({'groupId' : rule.groupId})
		if self.simulationParameters: 
			localSimulationParameters = self.simulationParameters.copy()
			localSimulationParameters.update({'ruleId' : rule.id, 'ruleText' : rule.getFullRepresentation()})
			parameters.update({'simulationParameters' : localSimulationParameters})

		driver = actionManager.getActionDriver(action, parameters)

		message = "Rule " + str(rule.id) + " (" + str(rule.buildingName)
		if rule.groupId: message += ".g[" + str(rule.groupId) + "]"
		if rule.roomName: message += ".r[" + str(rule.roomName) + "]"


		flash(message + ") actuated; consequent is '" + rule.consequent + "'...")
		try:
			driver.actuate()
		except Exception as e:
			flash(message + ") Erro while actuating the consequent '" + rule.consequent + "'... " + str(e), 'red')

		if not self.simulationParameters:
			rules = Rules()
			rules.setActiveRule(buildingName = rule.buildingName, roomName = rule.roomName, ruleId = rule.id)
	def getConflictingRules(self, roomName, buildingName, ruleBody):
		checkData(locals())

		ruleBody = ruleBody.strip()

		from app.backend.controller.triggerManager import TriggerManager
		from app.backend.controller.actionManager import ActionManager
		triggerManager = TriggerManager()
		actionManager = ActionManager()

		room = Room(buildingName = buildingName, roomName = roomName)
		room.retrieve()

		ruleList = room.getRules( includeGroupsRules = True,  includeDisabled = False)



		ruleAntecedent = ruleBody.split("then")[0].replace("if", "").strip()
		ruleConsequent = ruleBody.split("then")[1].strip()
		
		newRuleTranslatedTriggers = triggerManager.translateTrigger(ruleAntecedent)
		newRuleAction, originalModel, parameterValues = actionManager.getActionAndTemplateAndParameterValues(ruleConsequent)


		conflictingRuleList = []
		for rule in ruleList:

			currentRuleAction, originalModel, parameterValues = actionManager.getActionAndTemplateAndParameterValues(rule.consequent)
			savedRuleTranslatedTriggers = triggerManager.translateTrigger(rule.antecedent)			

			conflictingAntecedentFound = False
			
			for newRuleTrigger in newRuleTranslatedTriggers["triggers"]:

				for savedRuleTrigger in savedRuleTranslatedTriggers["triggers"]:
					
					if "between" not in newRuleTrigger["antecedent"]:

						if newRuleTrigger["antecedent"] == savedRuleTrigger["antecedent"] and (newRuleAction.category == currentRuleAction.category): 
							conflictingAntecedentFound = True

					else:

						# In the case of range based antecedent I cannot just check if it is equal but I have to see the trigger name
						if newRuleTrigger["trigger"].triggerName == savedRuleTrigger["trigger"].triggerName and (newRuleAction.category == currentRuleAction.category):
							conflictingAntecedentFound = True

					if conflictingAntecedentFound: break
				if conflictingAntecedentFound: break

			if conflictingAntecedentFound:
				conflictingRuleList.append({"ruleId" : rule.id, "ruleBody" : rule.getFullRepresentation()})



		return {"conflictingRules" : conflictingRuleList}
Exemple #3
0
	def test1(self):

		from app.backend.controller.triggerManager import TriggerManager
		from app.backend.controller.actionManager import ActionManager

		triggerManager = TriggerManager()
		print triggerManager.getTrigger("it is between 10.00 AM and 8.00 PM")
		print triggerManager.translateTrigger("it is between 10.00 AM and 8.00 PM")

		actionManager = ActionManager()
		print actionManager.getAction("turn on the heating")
Exemple #4
0
def translateAction():
    if request.method == "POST":

        sessionKey = validateInput(request.form["sessionKey"])
        userUuid = validateInput(request.form["userUuid"])
        consequent = validateInput(request.form["consequent"])

        try:
            session = SessionManager()
            session.checkSessionValidity(sessionKey, userUuid)
            actionManager = ActionManager()

            return returnResult(actionManager.translateAction(ruleConsequent=consequent, getDict=True))
        except Exception as e:
            return returnError(e)
Exemple #5
0
def ruleCategories(username=None):

    if request.method == "POST":

        sessionKey = validateInput(request.form["sessionKey"])
        userUuid = validateInput(request.form["userUuid"])

        try:
            session = SessionManager()
            session.checkSessionValidity(sessionKey, userUuid)
            userManager = UsersManager()

            from app.backend.controller.actionManager import ActionManager

            actionManager = ActionManager()
            categories = actionManager.getActionCategories()

            result = {"categories": categories}

            return returnResult(result)

        except Exception as e:
            return returnError(e)
	def __addOrModifyRule(self, priority = None, buildingName = None, roomName = None, authorUuid = None, ruleBody = None, ruleId = None, antecedent = None, consequent = None, enabled = True):
		checkData(locals())
		
		import time,datetime
		startTimeMilliseconds = long((time.time() + 0.5) * 1000)


		if ruleBody:
			try:
				antecedent = ruleBody.split("then")[0].replace("if ", "").strip()
				consequent = ruleBody.split("then")[1].strip()
			except Exception as e:
				raise NotWellFormedRuleError("There is a syntax error in the rule you are trying to save")

		
		# Detecting rule category (by the rule-consequent)
		from app.backend.controller.actionManager import ActionManager
		actionManager = ActionManager()
		category = actionManager.getAction(consequent).category
		
		from app.backend.model.user import User
		author = User(uuid = authorUuid)
		author.retrieve()

		if int(str(priority)) < 0 or int(str(priority)) > author.getMaxRoomPriority():
			raise RulePriorityError("You can specify rules for rooms with a priority value between 0 and " + str(author.getMaxRoomPriority()) + ". You inserted " + str(priority))



		from app.backend.model.rule import Rule
		from app.backend.model.room import Room

		if not ruleId:
			rule = Rule(priority = priority, category = category, buildingName = buildingName, roomName = roomName, authorUuid = authorUuid, antecedent = antecedent, consequent = consequent, enabled = True)
		else:
			rule = Rule(id = ruleId)
			rule.retrieve()
			author = rule.getAuthor()

			
			rule.antecedent = antecedent
			rule.consequent = consequent
			rule.authorUuid = authorUuid
			rule.authorUuid = authorUuid	
			rule.enabled = enabled		

			editor = rule.getAuthor()

			if editor.level < rule.getPriority():
				raise UserCredentialError("You cannot modify this rule since it has a too high priority for your user level")

		room = Room(buildingName = buildingName, roomName = roomName)
		room.retrieve()

		if not ruleId and not rule.checkIfUnique():
			raise DuplicatedRuleError("The submitted rule is already been saved for the considered room.")

		# excludedRuleId is needed to ignore the rule that the user want to edit
		excludedRuleId = ruleId if ruleId else None		

		roomRules = room.getRules(author = False, includeGroupsRules = True, excludedRuleId = excludedRuleId)

		# Checking that a priority is unique over the same category	
		for r in roomRules:
			if str(r.category) == str(category) and int(r.getPriority()) == int(priority):
				raise AlredyAssignedPriorityError("In room " + roomName + " the priority " + str(priority) + " has alredy been assigned to another rule with the same category!")

		temporaryRuleSet = []
		temporaryRuleSet.extend(roomRules)
		temporaryRuleSet.append(rule)

		#### OPTMIZATION ########################################################################################
		# Removing rules with a trigger that is different form the one of the rule I'm trying to insert or modify
		from app.backend.controller.triggerManager import TriggerManager
		triggerManager = TriggerManager()
		
		newRuleTriggers = triggerManager.translateTrigger(rule.antecedent)["triggers"]

		for i in range(0, len(temporaryRuleSet)):

			otherRuleTriggers = triggerManager.translateTrigger(temporaryRuleSet[i].antecedent)["triggers"]

			deleteRule = False

			if rule.category == temporaryRuleSet[i].category:
				for t1 in newRuleTriggers:
					for t2 in otherRuleTriggers:
						if t1 == t2:
							deleteRule = True
							break;
					if deleteRule: break;

			if deleteRule:
				del temporaryRuleSet[i]

		#### OPTMIZATION ########################################################################################


		for i in range(0, len(temporaryRuleSet)):
			temporaryRuleSet[i].groupId = None
			temporaryRuleSet[i].roomName = roomName


		from app.backend.controller.rulesetChecker import RulesetChecker
		rulesetChecker = RulesetChecker(temporaryRuleSet)
		ruleCheckErrorList = rulesetChecker.check()

		if len(ruleCheckErrorList) == 0:
			if ruleId: 
				rule.id = ruleId
				rule.setPriority(priority)


			from app.backend.commons.console import flash
			endTimeMilliseconds = long((time.time() + 0.5) * 1000)
			opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds
			flash("RoomRuleVerification [SUCCESS]: roomName = " + str(roomName) +" #rules=" + str(len(temporaryRuleSet)) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))


			return room.addRule(rule).getDict()
		else:
			from app.backend.commons.console import flash
			
			logMessage = "authorUuid =  " + str(authorUuid) + ", "
			logMessage += "buildingName =  " + str(buildingName) + ", "
			logMessage += "roomName =  " + str(roomName) + ", "
			logMessage += "ruleSetDescr =  " + str(temporaryRuleSet) + ", "
			logMessage += "newRule =  " + str(rule)

			flash("RuleValidationError: " + logMessage)

			endTimeMilliseconds = long((time.time() + 0.5) * 1000)
			opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds
			flash("RoomRuleVerification [FAILED]: roomName = " + str(roomName) +" #rules=" + str(len(temporaryRuleSet)) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))


			raise RuleValidationError(ruleCheckErrorList)
	def check(self):

		triggerManager = TriggerManager()
		actionManager = ActionManager()
		assertionTemplate = "(assert (=> @@RULE_ANTECEDENT@@ @@RULE_CONSEQUENT@@))"
		finalAssertionTemplate = "(assert (and @@FIRST_ARG@@ @@SECOND_ARG@@ ))"
		rangeTriggersName = {"EXT_TEMPERATURE_RANGE" : "(extTempInRoom 1)", "ROOM_TEMPERATURE_RANGE" : "(tempInRoom 1)", "DATE_RANGE" : "(day 1)", "TIME_RANGE" : "(time 1)"}

		theoremBody = []
		theoremAssertions = []

		parametersIntervals = {}

		for rule in self.ruleList:

			translatedTriggers = triggerManager.translateTrigger(rule.antecedent) 
			translatedConsequent, action, parameters = actionManager.translateAction(rule.consequent)

			translatedAntecedent = translatedTriggers["translation"]

			currentRuleAssertion = assertionTemplate.replace("@@RULE_ANTECEDENT@@", translatedAntecedent)
			currentRuleAssertion = currentRuleAssertion.replace("@@RULE_CONSEQUENT@@",  translatedConsequent)

			# Adding the current rule to the theorem body
			theoremBody.append(currentRuleAssertion)

			# Now saving, in case of range based trigger, which intervals has to be checked
			for translatedTrigger in translatedTriggers["triggers"]:
				trigger = translatedTrigger["trigger"]
				parameters = translatedTrigger["translatedParams"]

				if trigger.triggerName in rangeTriggersName.keys():
					
					if trigger.triggerName not in parametersIntervals.keys():
						parametersIntervals[trigger.triggerName] = []
					
					parametersIntervals[trigger.triggerName].append(int(parameters['0']))
					parametersIntervals[trigger.triggerName].append(int(parameters['1']))
				
				else:
					theoremAssertions.append('(assert ' + translatedAntecedent + ')')


		for triggerName in parametersIntervals.keys():
			
			intervals = sorted(parametersIntervals[triggerName])

			#theoremAssertions.append('(assert (< ' + rangeTriggersName[triggerName] + ' '  + str(intervals[0]) + '))')
			for i in range(1, len(intervals)):
				firstArg = '(>= ' + rangeTriggersName[triggerName] + ' '  + str(intervals[i-1]) + ')'
				secondArg = '(<= ' + rangeTriggersName[triggerName] + ' '  + str(intervals[i]) + ')'
				theoremAssertions.append(finalAssertionTemplate.replace("@@FIRST_ARG@@", firstArg).replace("@@SECOND_ARG@@", secondArg))

			for i in intervals:
				theoremAssertions.append('(assert (= ' + rangeTriggersName[triggerName] + ' '  + str(i) + '))')				
			

		partialOutputFile = ""
		#File Header and Settings
		f = open(self.__MAIN_PATH + "header_template.txt")
		lines = f.readlines()
		f.close()
		for line in lines:
			partialOutputFile += line

		for assertion in theoremBody:
			partialOutputFile += assertion + "\n"

		for assertion in theoremAssertions:
			outputFile = partialOutputFile + assertion  + "\n"
			outputFile += "(check-sat)" + "\n"

			temporaryFilePath = self.__MAIN_PATH + self.__addPrefixToFileName("test_smt.z3")

			theOutFile = open(temporaryFilePath,"w")
			theOutFile.write(outputFile)
			theOutFile.close()	

			execStr = self.__MAIN_PATH + "z3/bin/z3 -smt2 " + temporaryFilePath
			#print execStr
			
			try:
				z3Output = subprocess.check_output(execStr, shell=True)
				os.remove(temporaryFilePath)
								
				if "unsat" in z3Output:
					error =  "There is a conflict in the rules! " + assertion
					print error
					self.errorList.append(error)
					return self.errorList
			except Exception as e :
				raise RuleValidationEngineError("The rule validation engine failed during rule checking.")


		return []
	def __addOrModifyRule(self, priority = None, buildingName = None, groupId = None, authorUuid = None, ruleBody = None, ruleId = None):
		checkData(locals())

		import time,datetime
		startTimeMilliseconds = long((time.time() + 0.5) * 1000)
		

		try:
			antecedent = ruleBody.split("then")[0].replace("if ", "").strip()
			consequent = ruleBody.split("then")[1].strip()
		except Exception as e:
			raise NotWellFormedRuleError("There is a syntax error in the rule you are trying to save")

		from app.backend.controller.actionManager import ActionManager
		actionManager = ActionManager()
		category = actionManager.getAction(consequent).category

		from app.backend.model.user import User
		author = User(uuid = authorUuid)
		author.retrieve()

		if int(str(priority)) < 0 or int(str(priority)) > author.getMaxGroupPriority():
			raise RulePriorityError("You can specify rules for groups with a priority value between 0 and " + str(author.getMaxRoomPriority()) + ". You inserted " + str(priority))

		from app.backend.model.rule import Rule
		from app.backend.model.group import Group

		if not ruleId:
			rule = Rule(priority = priority, category = category, buildingName = buildingName, groupId = groupId, authorUuid = authorUuid, antecedent = antecedent, consequent = consequent, enabled = True)
		else:
			rule = Rule(id = ruleId)
			rule.retrieve()
			author = rule.getAuthor()

			
			rule.antecedent = antecedent
			rule.consequent = consequent
			rule.authorUuid = authorUuid

			editor = rule.getAuthor()

			if editor.level < rule.getPriority():
				raise UserCredentialError("You cannot modify this rule since it has a too high priority for your user level")

		group = Group(buildingName = buildingName, id = groupId)
		group.retrieve()

		if not ruleId and not rule.checkIfUnique():
			raise DuplicatedRuleError("The submitted rule is already been saved for the considered group.")

		# excludedRuleId is needed to ignore the rule that the user want to edit
		excludedRuleId = ruleId if ruleId else None		


		ruleCheckErrorList = []
		groupRoomList = group.getRooms()
		for room in groupRoomList:

			groupRules = group.getRules(excludedRuleId = excludedRuleId)

			# Checking that a priority is unique over the same category	
			for r in groupRules:
				if str(r.category) == str(category) and int(r.getPriority()) == int(priority):
					raise AlredyAssignedPriorityError("In group " + str(groupId) + " the priority " + str(priority) + " has alredy been assigned to another rule with the same category!")


			temporaryRuleSet = []
			temporaryRuleSet.extend(room.getRules(author = False, includeGroupsRules = True, excludedRuleId = False, excludeCrossRoomValidationRules = True))
			temporaryRuleSet.extend(groupRules)

			temporaryRuleSet.append(rule)


			from app.backend.controller.rulesetChecker import RulesetChecker
			rulesetChecker = RulesetChecker(temporaryRuleSet)

			ruleCheckErrorList.extend(rulesetChecker.check())

		if len(ruleCheckErrorList) == 0:
			
			if ruleId: 	#if i'm in edit mode
				rule.id = ruleId
				rule.setPriority(priority)

			# Disabling rules in all the groups rooms since they have to be validated again

			for room in groupRoomList:
			
				from app.backend.controller.notificationsManager import NotificationsManager
				notifications = NotificationsManager()
				messageSubject = "Group " +  str(groupId) + " changed your room " + str(room.roomName) + " policy."
				messageText =  "Some rules in group " + str(groupId) + " have been changed."
				notifications.sendNotification(buildingName = buildingName, roomName = room.roomName, messageSubject = messageSubject, messageText = messageText) 
				
				#for r in room.getRules(includeGroupsRules = False, excludeCrossRoomValidationRules = True):
				#	r.disable()

			from app.backend.commons.console import flash
			endTimeMilliseconds = long((time.time() + 0.5) * 1000)
			opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds
			flash("GroupsRuleVerification [SUCCESS]: groupId = " + str(groupId) +" #rules=" + str(len(temporaryRuleSet)) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))

			return group.addRule(rule).getDict()
		else:

			from app.backend.commons.console import flash
			
			logMessage = "authorUuid =  " + str(authorUuid) + ", "
			logMessage += "buildingName =  " + str(buildingName) + ", "
			logMessage += "gropuId =  " + str(groupId) + ", "
			logMessage += "ruleSetDescr =  " + str(temporaryRuleSet) + ", "
			logMessage += "newRule =  " + str(rule)

			flash("RuleValidationError: " + logMessage)

			endTimeMilliseconds = long((time.time() + 0.5) * 1000)
			opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds
			flash("GroupsRuleVerification [FAILED]: groupId = " + str(groupId) +" #rules=" + str(len(temporaryRuleSet)) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))

			raise RuleValidationError(ruleCheckErrorList + " Error in room " + room.roomName)