def EvaluateTrigger(self, event): try: ruleUID = None if (self._proxyHandler is not None): ruleUID = self._proxyHandler.getRuleUID() getLogger().debug( "EvaluateTrigger called for rule '{}' because item '{}' was changed or updated to state '{}' (Event='{}' RuleUID='{}')" .format(self.getName(), event.itemName, str(event.getState()), event.event, ruleUID)) newActiveState = False for curTriggerName, curTrigger in self._arrVirtualTriggers.iteritems( ): newActiveState = newActiveState or curTrigger.isActive() if (self.GetRequestedTriggerState() != newActiveState): self.SetRequestedTriggerState(newActiveState) #Do the update (which checks both Trigger and Conditions) self.UpdateState() except: LogException() return
def __init__(self, name, arrTimeSchedule, arrOutputItems, arrConditions=[], description=''): try: getLogger().debug(( "Initialize 'ScheduleRule': Name='{}, TimeSchedule='{}', OutputItems='{}', Conditions='{}'" ).format(name, arrTimeSchedule, arrOutputItems, arrConditions)) #Validate TimeIntervals for idx in range(len(arrTimeSchedule)): if (isinstance(arrTimeSchedule[idx], TimeInterval) == False): getLogger().error( "'" + name + "' has invalid TimeInterval at index " + str(idx) + ", a valid parameter must be of type 'TimeInterval'") self._configValid = False #First add conditions (assume they are easiest to evaluate) conditions = arrConditions conditions.append(TimeScheduleCondition(arrTimeSchedule)) #No TriggerItems! BaseRule.__init__(self, name, description, [], arrOutputItems, conditions) except: LogException() return
def __init__(self, name, description, arrTriggerItems, arrOutputItems, arrConditions): try: self.requestedTriggeredState = False self.actualTriggeredState = False BaseCore.__init__(self, name) self._description = description self._configValid = True self._mgr = None self._proxyHandler = None self._conditionMgr = ConditionManager() self._arrRequiredService = [] self._arrVirtualTriggers = {} self._arrVirtualSwitches = {} self._arrOutputItems = arrOutputItems self._arrTriggerItems = arrTriggerItems self._conditionMgr.Add(arrConditions) getLogger().debug(( "Created new rule '{}' - Triggers='{}', Outputs='{}', Conditions='{}'" ).format(name, self._arrTriggerItems, self._arrOutputItems, arrConditions)) except: LogException()
def runNow(self): try: if ((self._ruleUID is not None) and (getRuleManager() is not None)): getLogger().debug(("Manual execute rule '{}' UID='{}'").format(self.getConfigName(), self._ruleUID)) getRuleManager().runNow(self._ruleUID) except: LogException()
def createVirtualOutputAdvanced(self, virtualItemName, physicalDeviceName, actualItem, strSwitchPurpose = ""): curVirtualSwitch = None try: getLogger().debug("Create VirtualSwitch '" + str(physicalDeviceName) + "' for virtualItem='" + virtualItemName +"'") # 1. Get/Create Physical Switch # ###################################################################### physicalDevice = self.createPhysicalDevice(physicalDeviceName) if (physicalDevice == None): getLogger().error(("Unable to create PhysicalDevice for '{}'.").format(physicalDeviceName)) return None # 1. Create VirutalSwitch # ###################################################################### uniqueName = RuleManager.GenerateVirtualItemUniqueName(virtualItemName, physicalDevice.getName(), strSwitchPurpose) if (isinstance(actualItem, SwitchOutput)): curVirtualSwitch = VirtualSwitch(uniqueName, physicalDevice, actualItem.getActivateDelay(), actualItem.getDeactivateDelay()) elif (isinstance(actualItem, DimmerOutput)): curVirtualSwitch = VirtualDimmer(uniqueName, physicalDevice, actualItem.getActiveState(), actualItem.getDeactiveState(), actualItem.getActivateDelay(), actualItem.getDeactivateDelay()) else: curVirtualSwitch = VirtualSwitch(uniqueName, physicalDevice, actualItem.getActivateDelay(), actualItem.getDeactivateDelay()) if (self.dictVirtualSwitches.has_key(curVirtualSwitch.getId())): getLogger().error("VirtualSwitch with name '" + uniqueName + "' already exist") else: self.dictVirtualSwitches[curVirtualSwitch.getId()] = curVirtualSwitch getLogger().info("Added new VirtualSwitch '" + curVirtualSwitch.getName() + "' to dictionary") getLogger().debug("New VirtualSwicth dictionary: '" + str(self.dictVirtualSwitches) + "'") except: LogException() return curVirtualSwitch
def Add(self, arrConditions): try: for current in arrConditions: isValid = False curCondition = current if (isinstance(curCondition, basestring)): if (isItemBinaryType(curCondition)): condition = BinaryCriteria.CreateInstance(curCondition) curCondition = condition self.conditions.append(condition) isValid = True #TODO:: Do check if it supports conditions? elif (isinstance(curCondition, BaseCriteria)): self.conditions.append(curCondition) isValid = True if (isValid == False): getLogger().error( "Invalid condition added to ConditionManager. A string must refer to either a 'OnOff' or a 'OpenClosed' Item in openHAB (Condition='" + str(curCondition) + "')") return False getLogger().debug( ("Condition '{}' added to ConditionManager.").format( curCondition.getName())) except: LogException()
def Create(cls, itemName): try: curItem = scope.itemRegistry.getItem(itemName) getLogger().debug(("DeviceFactory: Item accepts datatypes: '{}'").format(curItem.getAcceptedDataTypes())) # # BinaryDevice # ############################################# #Check if we should create a OnOffDevice if (len(list(set(curItem.getAcceptedDataTypes()) & set(OnOffDevice.getAcceptedTypes())))>0): return OnOffDevice(itemName) #Check if we should create a OpenClosedDevice elif (len(list(set(curItem.getAcceptedDataTypes()) & set(OpenClosedDevice.getAcceptedTypes())))>0): return OpenClosedDevice(itemName) #Check if we should create a NumberDevice elif (len(list(set(curItem.getAcceptedDataTypes()) & set(NumberDevice.getAcceptedTypes())))>0): return NumberDevice(itemName, moduleName) #Check if we should create a StringDevice elif (len(list(set(curItem.getAcceptedDataTypes()) & set(StringDevice.getAcceptedTypes())))>0): return StringDevice(itemName) else: getLogger().error(("ItemType for '{}' not supported in DeviceFactory.Create()").format(itemName)) except: LogException() return None
def subscribeItemStateChangedEvent(self, ruleUID, itemName): try: triggerName = itemName getLogger().info("Adding ItemStateChangeTrigger for item '{}', triggerName='{}', ruleUID='{}'".format(itemName, triggerName, ruleUID)) self._subscribeTriggerEvent(ruleUID, itemName, ItemStateChangeTrigger(itemName, None, None, triggerName)) except: LogException()
def _evaluateViritualSwitch(self, curOffset, actSequence): activate = False getLogger().info(( "_evaluateViritualSwitch: actSequence='{}' curOffset='{}'").format( actSequence, curOffset)) try: for curSequence in actSequence: getLogger().info(( "Evaluate sequence '{}' (begin='{}' end='{}', curOffset='{}')" ).format(curSequence.getName(), curSequence.getBeginOffset(), curSequence.getEndOffset(), curOffset)) if ((curSequence.getBeginOffset() <= curOffset) and (curOffset < curSequence.getEndOffset())): getLogger().debug((" Light '{}' is ACTIVE").format( curSequence.getName())) activate = True break else: getLogger().debug((" Light '{}' is INACTIVE").format( curSequence.getName())) except: LogException() finally: getLogger().info(("_evaluateViritualSwitch: DONE! activate='{}'" ).format(activate)) return activate
def isIntervalActive(self): try: strBeginTime = self.getStartTime() strEndTime = self.getEndTime() dateToday = getDateToday() curTime = DateTime() calculatedStartTime = ParseTimeStringToDate(dateToday, self._begin) calculatedEndTime = ParseTimeStringToDate(dateToday, self._end) #End is before start -> interval is over midnight if calculatedEndTime.isBefore(calculatedStartTime): if (curTime.isAfter(calculatedStartTime)): calculatedEndTime = calculatedEndTime.plusDays(1) elif (curTime.isBefore(calculatedEndTime)): calculatedStartTime = calculatedStartTime.minusDays(1) else: calculatedEndTime = calculatedEndTime.plusDays(1) getLogger().debug(( "Processing interval '{}' - '{}' -> '{}' - '{}' - Current Time '{}', isActive='{}'" ).format(self.getStartTime(), self.getEndTime(), calculatedStartTime, calculatedEndTime, curTime, (curTime.isAfter(calculatedStartTime) and curTime.isBefore(calculatedEndTime)))) return (curTime.isAfter(calculatedStartTime) and curTime.isBefore(calculatedEndTime)) except: LogException() return False
def getPhysicalDevice(self, deviceName): if (self.dictPhysicalDevices.has_key(deviceName)==False): getLogger().warn("PhysicalDevice not found for '" + deviceName + "'") getLogger().debug(("PhysicalDevice dictionary -> {}").format(self.dictPhysicalDevices)) return None return self.dictPhysicalDevices[deviceName]
def AddItemCommandTrigger(self, itemName): try: triggerName = itemName getLogger().info("Adding ItemCommandTrigger for item='{}', trigger='{}'".format(itemName, triggerName)) self._AddTriggerCore(ItemCommandTrigger(itemName, triggerName=triggerName), triggerName) except: LogException()
def fireEvent(self, event): try: getLogger().debug("fireEvent called for '" + self.getName() + "' event='" + str(event) + "'") for key, value in self.callbacks.iteritems(): getLogger().debug("Calling callback for subscriber='" + str(key) + "'") value(event) except: LogException()
def AddItemStateUpdateTrigger(self, itemName): try: triggerName = itemName getLogger().info("Adding ItemStateUpdateTrigger for item='{}', trigger='{}'".format(itemName, triggerName)) newTrigger = ItemStateUpdateTrigger(itemName, triggerName=triggerName) self._AddTriggerCore(newTrigger, triggerName) except: LogException()
def StateChangedEvent(self, oldState, newState, eventStr): try: getLogger().debug("StateChangedEvent called for '" + self.getName() + "' oldState='" + oldState + "', newState='" + newState + "', event='" + eventStr + "'") self._state = newState self.fireStateChangedEvent(oldState, newState, eventStr) except: LogException() return False return True
def StateUpdatedEvent(self, state, eventStr): try: getLogger().debug("StateUpdatedEvent called for '" + self.getName() + "' state='" + state + "', event='" + eventStr + "'") self._state = state self.fireStateUpdatedEvent(state, eventStr) except: LogException() return False return True
def setEnabled(self, newState): try: if ((self._ruleUID is not None) and (getRuleManager() is not None)): getRuleManager().setEnabled(self._ruleUID, newState) getLogger().info("Enabled state of rule '{}', was changed to '{}'".format(self._ruleUID, newState)) else: getLogger().error("Not able to alter enabled state of rule '{}'".format(self._ruleUID)) except: LogException()
def isEnabled(self): try: if ((self._ruleUID is not None) and (getRuleManager() is not None)): return getRuleManager().isEnabled(self._ruleUID) else: getLogger().error("Not able to query enabled state of rule '{}'".format(self._ruleUID)) except: LogException() return False
def CreateInstance(cls, itemName): if (isItemOnOffType(itemName)): return OnOffCriteria(itemName) elif (isItemOpenClosedType(itemName)): return OpenClosedCriteria(itemName) getLogger().error( "BinaryCriteria could not be created for '%s', either a OnOff or a OpenClosed item is expected. The provided Item is none of those." % (itemName)) return None
def onEvent(self, event): try: getLogger().debug("Calling 'onEvent' for VirtualTrigger name='" + self.getName() + "'") newActiveState = False #TODO:: Make this generic if event.getState() in ('ON', 'OPEN'): newActiveState = True self.updateState(newActiveState) except: LogException()
def __init__(self, name, description, arrTriggerItems): try: getLogger().debug( ("Initialize 'MaintenanceRule': Name='{}").format(name)) #No Condition or Output items! BaseRule.__init__(self, name, description, arrTriggerItems, [], []) except: LogException() return
def __init__(self, name, physicalDevice, activeState, inactiveState, activateDelay, deactivateDelay): try: self._delayActivateTimer = None self._delayDeactivateTimer = None self._activeState = activeState self._inactiveState = inactiveState self.delayActivate = float(activateDelay) self.delayDeactivate = float(deactivateDelay) VirtualItem.__init__(self, name, physicalDevice, None) getLogger().info(("Create VirtualSwitch '{}' - states='{}'/'{}', delayActivate='{}', delayDeactivate='{}', type='{}' ").format(name, self._activeState, self._inactiveState, self.delayActivate, self.delayDeactivate, self.__class__.__name__)) except: LogException()
def getConfigValue(cfg, configKey, defaultValue=None, decode=False): if (configKey not in cfg) and (defaultValue is not None): getLogger().error( "Required config key '{}' not found in configuration".format( configKey)) elif configKey in cfg: if decode: return cfg[configKey].decode('utf8') else: return cfg[configKey] return defaultValue
def __init__(self, name): try: PhysicalDevice.__init__(self, name) curItem = scope.itemRegistry.getItem(self.getName()) strState = str(curItem.state).upper() getLogger().debug(("Initialize BinaryDevice '{}', current state is '{}' (Type='{}')").format(self.getName(), curItem.state, type(curItem.state))) if (strState == 'NULL'): getLogger().info(("BinaryDevice '{}' is in uninitialized state. Changing state from '{}' to state '{}'").format(self.getName(), curItem.state, self.getStateInactive())) events.sendCommand(curItem, self.getStateInactive()) except: LogException()
def EventHandler_CronJob(self): try: ruleUID = None if (self._proxyHandler is not None): ruleUID = self._proxyHandler.getRuleUID() getLogger().debug( ("Processing EventHandler_CronJob for '{}' (RuleUID='{}')" ).format(self.getName(), ruleUID)) self.UpdateState() self.onCronJob() except: LogException()
def runNow(self): try: ruleUID = None if (self._proxyHandler is not None): ruleUID = self._proxyHandler.getRuleUID() getLogger().debug( "calling 'runNow' for '{}' (ruleUID='{}')".format( self.getName(), ruleUID)) self.getProxyHandler().runNow() except: LogException() return
def isActive(self): try: for idx in range(len(self._schedules)): curInterval = self._schedules[idx] if (curInterval.isIntervalActive()): getLogger().debug( "TimeScheduleCondition 'isActive()' evaluates 'True'") return True except: LogException() getLogger().debug( "TimeScheduleCondition 'isActive()' evaluates 'False'") return False
def createPhysicalDevice(self, deviceName): try: # 1. Check that items exist in openHAB # ###################################################################### # 2. Check if it already exists in the dictionary, else create # ###################################################################### if (self.dictPhysicalDevices.has_key(deviceName)==False): getLogger().info("Creating new PhysicalDevice '" + deviceName + "'") device = DeviceFactory.Create(deviceName) if (device is None): getLogger().error(("New PhysicalDevice '{}' could not be created!!!!").format(deviceName)) return None self.dictPhysicalDevices[deviceName] = device getLogger().debug("New PhysicalDevice added to dictionary: '" + str(self.dictPhysicalDevices) + "'") getLogger().debug("Added new PhysicalDevice '" + deviceName + "' to triggers") except: LogException() return None # 3. return PhysicalDevice # ###################################################################### return self.dictPhysicalDevices[deviceName]
def createTriggerRule(self, cfgRule): cfgTriggers = cfgRule[KEY_TRIGGERS] cfgConditions = cfgRule[KEY_CONDITIONS] cfgOutputs = cfgRule[KEY_OUTPUTS] ruleName = getConfigValue(cfgRule, KEY_NAME) arrTriggers = self.processTriggers(ruleName, cfgTriggers) arrConditions = self.processConditions(ruleName, cfgConditions) arrOutputs = self.processOutputs(ruleName, cfgOutputs) getLogger().debug( "Loaded config for '{}' Triggers='{}', Conditions='{}', Outputs='{}'" .format(ruleName, arrTriggers, arrConditions, arrOutputs)) return StateTriggerRule(ruleName, arrTriggers, arrOutputs, arrConditions)
def __init__(self, configName, _name, _description, manager): try: self._id = str(uuid.uuid4()) self._ruleUID = None self._ruleObj = None self.name = _name self.description = _description self._manager = manager getLogger().debug("Creating new rule '{}'".format(configName)) self.triggers = [] self._configName = configName except: LogException()