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}
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")
def translateTrigger(): if request.method == "POST": sessionKey = validateInput(request.form["sessionKey"]) userUuid = validateInput(request.form["userUuid"]) antecedent = validateInput(request.form["antecedent"]) try: session = SessionManager() session.checkSessionValidity(sessionKey, userUuid) triggerManager = TriggerManager() return returnResult(triggerManager.translateTrigger(ruleAntecedent=antecedent, getDict=True)) except Exception as e: return returnError(e)
def test3(self): from app.backend.controller.triggerManager import TriggerManager triggerManager = TriggerManager() translatedTriggers = triggerManager.translateTrigger("someone is in the room, it is cloudy, it is rainy, time is between 10:00 and 11:00") print translatedTriggers["translation"] for trigger in translatedTriggers["triggers"]: print trigger["translation"] print trigger["trigger"] print trigger["translatedParams"] ruleList = [] from app.backend.model.rule import Rule ruleList.append(Rule())
def checkRuleTrigger(self, rule): triggerManager = TriggerManager() #trigger, originalModel, parameters = triggerManager.getTriggerAndTemplateAndParameterValues(rule.antecedent) translatedTriggers = triggerManager.translateTrigger(rule.antecedent) message = "Rule " + str(rule.id) + " (" + str(rule.buildingName) flash(message + ") checking the '" + rule.antecedent + "'...", "gray") for triggerInfo in translatedTriggers["triggers"]: trigger = triggerInfo["trigger"] parameters = triggerInfo["parameterValues"] 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 = triggerManager.getTriggerDriver(trigger, parameters) if rule.groupId: message += ".g[" + str(rule.groupId) + "]" if rule.roomName: message += ".r[" + str(rule.roomName) + "]" try: if driver.eventTriggered(): flash(message + ") the antecedent portion '" + trigger.ruleAntecedent + "' is TRUE...", "green") else: flash(message + ") the antecedent portion '" + trigger.ruleAntecedent + "' is FALSE...", "red") flash(message + ") NOT ACTUATED - the antecedent '" + rule.antecedent + "' is FALSE...", "red") return False except Exception as e: flash(message + ") error while reading the trigger! " + str(e), 'red') return False flash(message + ") ACTUATED the antecedent '" + rule.antecedent + "' is TRUE...", "green") return True
def getRules(self, roomName, buildingName, username = None, includeGroupsRules = False, orderByPriority = False, includeDisabled = False, categoriesFilter = None, includeTriggerCategory = False): checkData(locals(), ["categoriesFilter"]) if categoriesFilter: checkData(json.loads(categoriesFilter)) room = Room(buildingName = buildingName, roomName = roomName) room.retrieve() ruleList = [] if username: from app.backend.model.user import User user = User(username = username) user.retrieve() ruleList = room.getRules( author = user, includeGroupsRules = includeGroupsRules, includeDisabled = includeDisabled, categoriesFilter = categoriesFilter) else: ruleList = room.getRules( includeGroupsRules = includeGroupsRules, includeDisabled = includeDisabled , categoriesFilter = categoriesFilter) if orderByPriority: ruleList = sorted(ruleList, key=lambda rule: rule.getPriority(), reverse=True) response = [] for rule in ruleList: ruleDict = rule.getDict(buildingName = buildingName, roomName = roomName) if includeTriggerCategory: from app.backend.controller.triggerManager import TriggerManager triggerManager = TriggerManager() triggers = triggerManager.translateTrigger(rule.antecedent)["triggers"] triggersCategory = [] for trigger in triggers: if trigger["trigger"].category not in triggersCategory: triggersCategory.append(trigger["trigger"].category) ruleDict.update({'triggersCategory' : triggersCategory}) response.append(ruleDict) return {"rules" : response}
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 []