def post_update_if_different(item_or_item_name, new_value, sendACommand=False, floatPrecision=None): """ Checks if the current state of the item is different than the desired new state. If the target state is the same, no update is posted. sendCommand vs postUpdate: If you want to tell something to change (turn a light on, change the thermostat to a new temperature, start raising the blinds, etc.), then you want to send a command to an Item using sendCommand. If your Items' states are not being updated by a binding, the autoupdate feature or something else external, you will probably want to update the state in a rule using ``events.postUpdate``. Unfortunately, most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine. Therefore, comparing the stored value with the new value will most likely always result in a difference. You can supply the named argument floatPrecision to round the value before comparing. Args: item_or_item_name (Item or str): name of the Item new_value (State or Command): state to update the Item with, or Command if using sendACommand (must be of a type supported by the Item) sendACommand (Boolean): (optional) ``True`` to send a command instead of an update floatPrecision (int): (optional) the precision of the Item's state to use when comparing values Returns: bool: ``True``, if the command or update was sent, else ``False`` """ compare_value = None item = itemRegistry.getItem(item_or_item_name) if isinstance(item_or_item_name, basestring) else item_or_item_name if sendACommand: compare_value = TypeParser.parseCommand(item.acceptedCommandTypes, str(new_value)) else: compare_value = TypeParser.parseState(item.acceptedDataTypes, str(new_value)) if compare_value is not None: if item.state != compare_value or (isinstance(new_value, float) and floatPrecision is not None and round(item.state.floatValue(), floatPrecision) != new_value): if sendACommand: events.sendCommand(item, new_value) LOG.debug(u"New sendCommand value for '{}' is '{}'".format(item.name, new_value)) else: events.postUpdate(item, new_value) LOG.debug(u"New postUpdate value for '{}' is '{}'".format(item.name, new_value)) return True else: LOG.debug(u"Not {} {} to '{}' since it is the same as the current state".format("sending command" if sendACommand else "posting update", new_value, item.name)) return False else: LOG.warn(u"'{}' is not an accepted {} for '{}'".format(new_value, "command type" if sendACommand else "state", item.name)) return False
def postUpdate(item_or_item_name, new_value): """ Posts an update to an item regardless of its current state. Args: item_name (Item or str): Item or name of the Item new_value (State): state to update the Item with """ item = itemRegistry.getItem(item_or_item_name) if isinstance( item_or_item_name, basestring) else item_or_item_name events.postUpdate(item, new_value)
def postUpdate(item_or_item_name, new_value): """ Posts an update to an item regardless of its current state. Args: item_name (Item or str): Item or name of the Item new_value (State): State to update the Item with """ LOG.warn("The 'core.utils.postUpdate' function is pending deprecation.") item = itemRegistry.getItem(item_or_item_name) if isinstance(item_or_item_name, basestring) else item_or_item_name events.postUpdate(item, new_value)
def __update_item__(self): """Rounds the remaining time on the Timer to the nearest second and updates the Item based on the Item's type. """ item = ir.getItem(self.count_item) if isinstance(item, NumberItem): events.postUpdate(self.count_item, str(round(self.time_left.total_seconds()))) else: rounded_secs = round(self.time_left.total_seconds()) rounded = timedelta(seconds=rounded_secs) events.postUpdate(self.count_item, str(rounded))
def lock(self): self.locking_level = self.locking_level + 1 if self.locking_level == 1: # went from unlocked to locked, manage area timer if self.occupancy_timer: # timer is running, store time remaining self.seconds_left_when_locked = seconds_between( DateTime.now(), self.occupancy_timeout) # save seconds left log.warn( "Occupancy Locking turned on, time left in minutes {}". format(int(self.seconds_left_when_locked / 60))) # cancel running timer self.cancel_timer() # update locking state events.postUpdate(self.occupancy_locking_item, 'ON')
def timer_body(target, value, is_command, time, log): """ Called when the differed action timer expires, sends the command to the target Item. Arguments: - target: Item name to send the command to - value: Command or state to issue to the target Item - is_command: Whether to send value to target as a command or an update - time: the original time string - log: logger passed in from the Rule that is using this. """ log.debug("{} {} to {} after {}".format( "Commanding" if is_command else "Updating", target, value, time)) if is_command: events.sendCommand(target, str(value)) else: events.postUpdate(target, str(value))
def execute(self, module, inputs): try: events.postUpdate(self.trigger_item_name, str(OnOffType.OFF)) events.postUpdate(self.result_item_name, None) status, result = _run_test(self.test_case) events.postUpdate(self.result_item_name, result) except: import traceback self.logger.error(traceback.format_exc())
def unlock(self): self.locking_level = self.locking_level - 1 if self.locking_level == 0: # area unlocked # restart timer if time was left on it if self.seconds_left_when_locked is not None: if self.is_area_occupied(): #area occupied, restart timer log.warn( "Occupancy Locking turned off for area {}, Timer restarted with time left {} minutes " .format(self.name, int(self.seconds_left_when_locked / 60))) self.start_timer(self.seconds_left_when_locked) self.seconds_left_when_locked = None else: log.info( "Occupancy Locking turned off for area {}, area vacant and timer NOT restarted" .format(self.name)) if self.locking_level < 0: self.locking_level = 0 # update locking state if self.locking_level == 0: events.postUpdate(self.occupancy_locking_item, 'OFF')
def update_group_OS_item( self, state ): # use updates to change OS state, commands are sent from external actions/scripts events.postUpdate( self.occupancy_state_item, state ) # post update NOT send command, exteral actions in scripts use send command to set OS state