Exemplo n.º 1
0
	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)
Exemplo n.º 2
0
def start():
	flash("BuildingRules DatabaseDumper is active...")
	while(1):
		try:
			main()
		except Exception as e:
			import logging
			logging.exception("")
			flash(e.message)

		time.sleep(43200)
Exemplo n.º 3
0
def start():
	flash("BuildingRules WeatherService is active...")
	while(1):
		try:
			main()
		except Exception as e:
			import logging
			logging.exception("")
			flash(e.message)

		time.sleep(600)
Exemplo n.º 4
0
def main():

	flash("Dumping database...")

	
	ts = time.time()
	st = datetime.datetime.fromtimestamp(ts).strftime('%Y_%m_%d_%H_%M_%S')
	fileName = "db_dump_" + st + ".sql"

	if not os.path.exists(__SERVICE_FILE_PATH):
		os.makedirs(__SERVICE_FILE_PATH)

	cmd = "mysqldump -u root -pbuildingdepot building_rules > " + __SERVICE_FILE_PATH + fileName
	
	flash(cmd)
	os.system(cmd)
Exemplo n.º 5
0
def start():
	flash("BuildingRules Deamon is active...")

	actionExecutor = ActionExecutor()

	while(1):
		try:
			actionExecutor.start()
		except Exception as e:
			import logging
			logging.basicConfig(filename='logs/deamon.log')
			logging.getLogger().addHandler(logging.StreamHandler())			
			logging.exception("")
			flash(e.message)

		time.sleep(600)
Exemplo n.º 6
0
	def test6(self):

		print "hi i'm here!!"

		from app.backend.model.buildings import Buildings		
		from app.backend.controller.rulesetChecker import RulesetChecker	
		import random	
		import time,datetime
		from app.backend.commons.console import flash

		buildings = Buildings()
		
		for building in buildings.getAllBuildings():
			buildingRules = building.getRules()


			for ruleNumber in range(0,81):		
				print "Testing with ruleNumber " + str(ruleNumber)
				for testNumber in range(0, 250):
					print "Testing with ruleNumber " + str(ruleNumber) + " #iteration: " + str(testNumber)
					tmpRuleSet = []
					tmpRuleIndex = []

					#Creating the temporary ruleset
					for i in range(0, ruleNumber):
						selectedRule = random.randint(0,len(buildingRules)-1)
						if selectedRule not in tmpRuleIndex:
							tmpRuleIndex.append(selectedRule)
							tmpRuleSet.append(buildingRules[selectedRule])

					rulesetChecker = RulesetChecker(tmpRuleSet)
		
					startTimeMilliseconds = long((time.time() + 0.5) * 1000)
					ruleCheckErrorList = rulesetChecker.check()
					endTimeMilliseconds = long((time.time() + 0.5) * 1000)
					
					opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds

					if len(ruleCheckErrorList) == 0:
						flash("EXPERIMENT-TestRoomRuleVerification [SUCCESS]:" + "#rules=" + str(ruleNumber) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))
					else:
						flash("EXPERIMENT-TestRoomRuleVerification [FAILED]:" + "#rules=" + str(ruleNumber) + " - opTimeMilliseconds:" + str(opTimeMilliseconds))

			print "DONE."
Exemplo n.º 7
0
def main():

	flash("Getting user list...")

	users = Users()
	userList = users.getAllUsers()

	notificationsManager = NotificationsManager()

	for user in userList:
		
		flash("Looking for " + str(user.uuid) + ":" + user.username + " notifications...")
		
		notificationList = notificationsManager.getNotifications(userUuid = str(user.uuid), username = user.username, automaticallySetAsRead = False)


		if len(notificationList["notifications"]):

			recipientUuid = notificationList["notifications"][0]["recipientUuid"]

			messageText = ""
			
			for notification in notificationList["notifications"]:
				messageText += notification["messageSubject"] + " (" + notification["sendTimestamp"] + ")" + "\n"
				messageText += "----------------------------------------------------" + "\n"
				messageText += notification["messageText"] + "\n"
				messageText += "\n\n\n"

		
			messageSubject = "[BUILDING RULES] - Notifications report"
			flash("Sending report to " + str(user.uuid) + ":" + user.username + ":" + user.email)
			notificationsManager.sendNotificationByEmail(recipientUuid = recipientUuid, messageSubject = messageSubject, messageText = messageText)
Exemplo n.º 8
0
def main():

	flash("Updating weather informations...")

	restReadDone = False
	try:
		url = 'http://api.openweathermap.org/data/2.5/weather?q=LA,us'
		response = urllib2.urlopen(url).read()
		restReadDone = True
	except Exception as e:
		flash(e.message)

	if restReadDone:

		if not os.path.exists(__SERVICE_FILE_PATH):
			os.makedirs(__SERVICE_FILE_PATH)

		if os.path.exists(__SERVICE_FILE_PATH + "weather.json"):
			shutil.copy2(__SERVICE_FILE_PATH + "weather.json", __SERVICE_FILE_PATH + "weather.old.json")
		
		out_file = open(__SERVICE_FILE_PATH + "weather.json","w")
		out_file.write(response)
		out_file.close()
Exemplo n.º 9
0
	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)
Exemplo n.º 10
0
	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
Exemplo n.º 11
0
	def start(self):

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

		analyzedRoomCounter = 0

		flash("Starting the actuation process...", "yellow")

		buildings = Buildings()
		buildingsManager = BuildingsManager()
		groupsManager = GroupsManager()
		rules = Rules()

		rules.resetActiveRules()
		
		for building in buildings.getAllBuildings():

			flash("Working on building '" + building.buildingName + "'...", "blue")

			triggeredRules = []
			triggeredRulesId = []
			
			# Getting all the triggered rules for the considered building	
			buildingRules = building.getRules()

			if len(buildingRules) == 0:
				flash("Nothing to do...")

			if len(buildingRules):
				for rule in buildingRules:

					if rule.roomName and not rule.groupId:

						if self.skipRuleOnRoomFilter(buildingName = building.buildingName, roomName = rule.roomName): continue
						analyzedRoomCounter += 1

						if self.checkRuleTrigger(rule):
							# If the antecedent of the rule is triggered, let us store the rule as triggered!
							triggeredRules.append(rule)
							triggeredRulesId.append(rule.id)
					
					elif rule.groupId and not rule.roomName:

						groupRoomList = groupsManager.getRooms(buildingName = building.buildingName, groupId = rule.groupId)["rooms"]
						for room in groupRoomList:

							if self.skipRuleOnRoomFilter(buildingName = building.buildingName, roomName = room.roomName): continue

							roomName = room["roomName"]
							newRule = copy.copy(rule)			# I need to copy the object to modify the room name
							newRule.roomName = roomName

							if self.checkRuleTrigger(newRule):
								# If the antecedent of the rule is triggered, let us store the rule as triggered!
								triggeredRules.append(newRule)
								triggeredRulesId.append(newRule.id)



				flash(building.buildingName + " - Total rules: " + str(len(buildingRules)), "gray")
				flash(building.buildingName + " - Triggered rules: " + str(len(triggeredRules)), "gray")


				# Now, let us partition rules among "Pure-Room-Rules" and "CRVG-Rules"
				roomScheduledRules = {}
				crvgScheduledRules = {}

				for rule in triggeredRules:



					if rule.roomName:

						# In this case we are selecting the rules spiecified for a specific room.
						# If the rule (for a specific category) is saved into a room belonging to a CRVG, I have to save it into the crvgScheduledRules set.
						# If the rule is not part of CRVG ruleset, then it is savet into the roomScheduledRules set.

						buildingName = building.buildingName
						roomName = rule.roomName
						validationCategories = [rule.category]
						crvgList = buildingsManager.getCrossRoomValidationGroups(buildingName = buildingName, roomName = roomName, validationCategories = validationCategories)

						if len(crvgList) == 0:


							if not roomName in roomScheduledRules.keys():
								roomScheduledRules[roomName] = []

							roomScheduledRules[roomName].append(rule)

						elif len(crvgList) == 1:

							
							if not crvgList[0].id in crvgScheduledRules.keys():
								crvgScheduledRules[crvgList[0].id] = []
							
							rule.gropuId = crvgList[0].id
							crvgScheduledRules[crvgList[0].id].append(rule)

						else:
							raise WrongBuildingGroupRipartitionError(roomName + " has been found to be part of two different Cross Room Validation Groups. This is not allowed.")

					elif rule.groupId and not rule.roomName:


						# Here we are selecting those rules that have been specified of a specific group.
						# Those groups can be standard groups or CRV GROUPS on a specific category. In the first case, i have to add a copy of the rule in each of the group rooms.
						# In the second case I have to add the rule to the corresponding CRVG dict (if the rule category is right).

						if groupsManager.isCrossRoomsValidationGroup(buildingName = building.buildingName, groupId = rule.groupId, crossRoomsValidationCategory = rule.category):

							if not rule.groupId in crvgScheduledRules.keys():
								crvgScheduledRules[rule.groupId] = []
							
							crvgScheduledRules[rule.groupId].append(rule)

						else:		
							raise UnknownError("Unexpected error into the database.")




					else:
						raise UnknownError("The rule with id " + rule.id + " has both the groupId and roomName field not null.")

				flash(building.buildingName + " - Number of rooms: " + str(len(roomScheduledRules.keys())), "gray")
				flash(building.buildingName + " - Number of CRV Groups: " + str(len(crvgScheduledRules.keys())), "gray")

				actuatedRulesCounter = 0

				flash("Executing actions for rooms...", "yellow")
				# Executing the rules per each room
				# In the case I have the same action category, I'll take the action with higher priority
				for roomName in roomScheduledRules.keys():
					flash("Room [" + building.buildingName + "." + roomName + "]..." , "blue")				
					ruleList = roomScheduledRules[roomName]
					#Let us order by rule priority
					ruleList = sorted(ruleList, key=lambda rule: rule.getPriority(), reverse=True)

					alreadyAppliedCategories = []
					for rule in ruleList:
							
						if rule.category not in alreadyAppliedCategories:

							alreadyAppliedCategories.append(rule.category)
							self.executeRule(rule)
							actuatedRulesCounter += 1
						else:
							flash(building.buildingName + " - Room " + roomName + ", ruleId " + str(rule.id) + " ignored.")

				flash("Executing actions for CRV Groups...", "yellow")
				for crvgId in crvgScheduledRules.keys():
					flash("Group " + building.buildingName + ".g[" + str(crvgId) + "]..." , "blue")				
					ruleList = crvgScheduledRules[crvgId]

					#Let us order by rule priority
					ruleList = sorted(ruleList, key=lambda rule: rule.getPriority(), reverse=True)

					alreadyAppliedCategories = []
					for rule in ruleList:
						if rule.category not in alreadyAppliedCategories:
							alreadyAppliedCategories.append(rule.category)
							self.executeRule(rule)
							actuatedRulesCounter += 1
						else:
							flash(building.buildingName + " - CRVGroup " + str(crvgId) + ", ruleId " + str(rule.id) + " ignored.")
							self.notifyIgnoredRule(rule)

		flash("The actuation process is ended.", "yellow")		
		endTimeMilliseconds = long((time.time() + 0.5) * 1000)
		opTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds
		flash("RunTimeRuleActuation:::RoomFilter=" + str(self.roomFilter) + "::Time=" + str(opTimeMilliseconds) + "::NumberOfRules:" + str(analyzedRoomCounter) + "::TriggeredRules:" + str(len(triggeredRules)) + "::ActuatedRules:" + str(actuatedRulesCounter) + "::IgnoredRules:" + str(len(triggeredRules)-actuatedRulesCounter))
Exemplo n.º 12
0
	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)