def get_times(): """Gets the list of Items that define the start times for today. It uses Ephemeris to determine which set of Items to select. The hierarchy is: - custom: custom defined holidays - holiday: default holidays - dayset: custom defined dayset - weekend: weekend as defined in Ephemeris - weekday: not weekend days - default: used when no other day type is detected for today Returns: - a list of names for DateTime Items; None if no valid start times were found. """ def cond(lst, cond): return [i for i in lst if cond(i)] def types(type): return [ i for i in items if get_key_value(i, NAMESPACE, "type") == type ] # Get all of the etod Items that are valid for today. start_times = { 'default': types("default"), 'weekday': types("weekday") if not Ephemeris.isWeekend() else [], 'weekend': types("weekend") if Ephemeris.isWeekend() else [], 'dayset': cond( types('dayset'), lambda i: Ephemeris.isInDayset( get_key_value(i, NAMESPACE, "set"))), 'holiday': cond(types('holiday'), lambda i: Ephemeris.isBankHoliday()), 'custom': cond( types('custom'), lambda i: Ephemeris.isBankHoliday( 0, get_key_value(i, NAMESPACE, "file"))) } # Determins which start time Items to use according to the hierarchy. day_type = None if start_times['custom']: day_type = 'custom' elif start_times['holiday']: day_type = 'holiday' elif start_times['dayset']: day_type = 'dayset' elif start_times['weekend']: day_type = 'weekend' elif start_times['weekday']: day_type = 'weekday' elif start_times['default']: day_type = 'default' log.info("Today is a {} day, there are {} time periods today.".format( day_type, len(start_times[day_type]))) return start_times[day_type] if day_type else None
def mode_or_lux_change(event): """ This rule iterates through all triggering groups and replays all actions for groups that are currently active, using the current mode and lux level. """ #start_time = DateTime.now().getMillis() mode_change_or_system_start = ( event.itemName == "Mode") if event is not None else True if not mode_change_or_system_start: lux_current = items[ area_triggers_and_actions_dict["lux_item_name"]] lux_previous = event.oldItemState spanned = False # get a list of active trigger groups (or all of them, if system started) for trigger_group in [ group for group in itemRegistry.getItem("gArea_Trigger").members if (group.state in [ON, OPEN] if event is not None else True) ]: action_groups = itemRegistry.getItems( trigger_group.name.replace("_Trigger", "_Action")) action_group = action_groups[0] if action_groups else None if action_group: for item in action_group.members: low_lux_trigger = get_key_value( item.name, "area_triggers_and_actions", "modes", str(items["Mode"]), "low_lux_trigger") or area_triggers_and_actions_dict[ "default_levels"]["low_lux_trigger"] # replay actions for all lights on mode change and system start, or only the lights affected on a lux change if mode_change_or_system_start or min( lux_previous.intValue(), lux_current.intValue()) <= low_lux_trigger <= max( lux_previous.intValue(), lux_current.intValue()): action_function_names = get_key_value( item.name, "area_triggers_and_actions", "actions").keys() if not action_function_names or "light_action" in action_function_names: start_action( item, True if event is not None else trigger_group.state in [ON, OPEN], "light_action") if mode_change_or_system_start: mode_or_lux_change.log.info( "Mode adjust: [{}]: {}: {}".format( items["Mode"], action_group.name, item.name)) else: spanned = True mode_or_lux_change.log.info( "Lux adjust: {}: {}: current=[{}], previous=[{}]" .format(action_group.name, item.name, lux_current, lux_previous)) if not mode_change_or_system_start and not spanned: mode_or_lux_change.log.debug( "No lights were adjusted: current=[{}], previous=[{}]".format( lux_current, lux_previous))
def refreshImageItem(itemName): refreshImageItem.log = logging.getLogger( "{}.grafanaRefreshInit".format(LOG_PREFIX)) panelUrl = GRAFANA_URL + "&panelId=" + \ str(get_key_value(itemName, "Grafana_Graphs", "PanelId")) + \ "&from=" + str(get_key_value(itemName, "Grafana_Graphs", "RangeFrom")) rangeTo = str(get_key_value(itemName, "Grafana_Graphs", "RangeTo")) if rangeTo != "": panelUrl += "&to=" + rangeTo panelUrl += "&theme=" + str( get_key_value(itemName, "Grafana_Graphs", "Theme")) refreshImageItem.log.debug("Refresh Item URL [{}]".format(panelUrl)) imageSnapshot = getSnapshotImage(panelUrl, itemName) events.postUpdate(itemName, imageSnapshot)
def grafanaRefresh(event): if ir.getItems(GRAFANA_GROUP) == []: addGrafanaItems() # Just in case for item in ir.getItem(GRAFANA_GROUP).members: lastRefresh = get_key_value(item.name, "Grafana_Graphs", "LastRefresh") grafanaRefresh.log.debug("Last refresh time for [{}] was [{}]".format( item.name, lastRefresh)) if minutes_between(lastRefresh, DateTime.now()) >= get_key_value( item.name, "Grafana_Graphs", "RefreshRate"): refreshImageItem(item.name) set_metadata(item.name, "Grafana_Graphs", {"LastRefresh": DateTime.now()}) grafanaRefresh.log.debug( "New refresh time for [{}] set to [{}]".format( item.name, get_key_value(item.name, "Grafana_Graphs", "LastRefresh")))
def item_init(event): """Rule that triggers at System started and populates Items with an initial value. The initialization value is defined in metadata with three key/values. - value: value to send update the Item to - override: optional boolean value to override the state of the Item even if it isn't NULL, defaults to "False". - clear: optional boolean value to delete the metadata once the Item is updated. Defaults to "False". For example: - { init="ON"[override="true", clear="true"] }: Initialize the Switch Item to ON whether or not it already has a value and then delete the metadata. - { init="123,45,67" }: Initialize the Color Item to the value only if it is NULL or UNDEF. Limitations: - The clear option only works for Items not created through .items files. For Items defined in .items files, you must manually remove the metadata or else it will get reloaded next time the file is loaded. """ item_init.log.info("Initializing Items") for item_name in [i for i in items if get_metadata(i, "init")]: value = get_value(item_name, "init") # Always update if override is True if get_key_value(item_name, "init", "override") == "True": post_update_if_different(item_name, value) item_init.log.info( "Overriding current value {} of {} to {}".format( items[item_name], item_name, value)) # If not overridden, only update if the Item is currently NULL or UNDEF. elif isinstance(items[item_name], UnDefType): item_init.log.info("Initializing {} to {}".format( item_name, value)) postUpdate(item_name, value) # Delete the metadata now that the Item is initialized. if get_key_value(item_name, "init", "clear") == "true": item_init.log.info( "Removing init metadata from {}".format(item_name)) remove_metadata(item_name, "init")
def addGrafanaItems(): addGrafanaItems.log = logging.getLogger( "{}.addGrafanaItems".format(LOG_PREFIX)) # scriptExtension.importPreset("RuleSupport") # Add Grafana Group if it doesn't exist if ir.getItems(GRAFANA_GROUP) == []: addGrafanaItems.log.info("Create Group [{}]".format(GRAFANA_GROUP)) add_item(GRAFANA_GROUP, item_type="Group", label="Grafana Snapshot images", tags=["Grafana"]) try: for entry in grafImgDict.values(): imgItemName = entry.get("item_name") if ir.getItems(imgItemName) == []: add_item(imgItemName, item_type="Image", groups=[GRAFANA_GROUP], label=entry.get("item_description"), tags=["Grafana"]) grafanaChannel = "ftpupload:imagereceiver:ftp_" + imgItemName + ":image" addGrafanaItems.log.info( "Created item [{}], link channel [{}]".format( imgItemName, grafanaChannel)) add_link(imgItemName, ChannelUID(grafanaChannel)) set_metadata(imgItemName, "Grafana_Graphs", \ {"PanelId": entry.get("grafana_panelid"), \ "RefreshRate": entry.get("image_refresh"), \ "RangeFrom": entry.get("grafana_range_from"), \ "RangeTo": entry.get("grafana_range_to"), \ "Theme": entry.get("grafana_theme"), \ "LastRefresh": entry.get("last_refresh")}, overwrite=True) addGrafanaItems.log.info("Metadata set [{}] [{}] [{}] [{}]".format( get_key_value(imgItemName, "Grafana_Graphs", "PanelId"), get_key_value(imgItemName, "Grafana_Graphs", "RefreshRate"), get_key_value(imgItemName, "Grafana_Graphs", "Theme"), get_key_value(imgItemName, "Grafana_Graphs", "LastRefresh"))) except: import traceback addGrafanaItems.log.error(traceback.format_exc())
def area_triggers(event): """ This rule triggers when any area trigger group becomes active. If there is an action group associated with the trigger group, the action function specified in the metadata of each of the group's members will be executed using that Item. If the Item does not have an action function in its metadata, the default action function will be used from ``configuration.area_triggers_and_actions_dict["default_action_function"]``. If the trigger group has an action function in its metadata, that function will also be executed using the trigger group. """ #start_time = DateTime.now().getMillis() if items["Mode"] != StringType("Security"): area_triggers.log.debug("{}: [{}]".format(event.itemName, event.itemState)) active = event.itemState in [ON, OPEN] action_groups = itemRegistry.getItems( event.itemName.replace("_Trigger", "_Action")) if action_groups: action_group = action_groups[0] #area_triggers.log.warn("Test: start loop: {}: [{}]: time=[{}]".format(event.itemName, event.itemState, DateTime.now().getMillis() - start_time)) for item in action_group.members: action_function_names = get_key_value( item.name, "area_triggers_and_actions", "actions").keys() if not action_function_names: action_function_names.append( area_triggers_and_actions_dict.get( "default_action_function")) for action_function_name in action_function_names: start_action(item, active, action_function_name) #area_triggers.log.warn("Test: end loop: {}: [{}]: time=[{}]".format(event.itemName, event.itemState, DateTime.now().getMillis() - start_time)) else: area_triggers.log.debug("No action group found for [{}]".format( event.itemName)) trigger_function_names = get_key_value(event.itemName, "area_triggers_and_actions", "actions").keys() for trigger_function_name in trigger_function_names: start_action(itemRegistry.getItem(event.itemName), active, trigger_function_name)
def light_action(item, active): """ This function performs an action on a light Item. When called, this function pulls in the metadata for the supplied Item or uses the default values specified in ``configuration.AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION"["default_levels"]``, if the metadata does not exist. This metadata is then compared to the current lux level to determine if a light should be turned OFF or set to the specified level. This function should work for everyone without modification. Args: Item item: The Item to perform the action on boolean active: Area activity (True for active and False for inactive) """ #start_time = DateTime.now().getMillis() item_metadata = get_key_value(item.name, "area_triggers_and_actions", "light_action") lux_item_name = item_metadata.get("lux_item_name", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"].get("lux_item_name")) trigger_type = "active" if active else "inactive" lux_trigger = item_metadata.get(trigger_type, {}).get("modes", {}).get(items[MODE_ITEM].toString(), {}).get("lux_trigger", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"]["default_levels"][trigger_type]["lux_trigger"]) lux_type = "low_lux" if lux_trigger == 0 or lux_item_name is None or items[lux_item_name].intValue() < lux_trigger else "high_lux" levels = item_metadata.get(trigger_type, {}).get("modes", {}).get(items[MODE_ITEM].toString(), {}).get(lux_type, {}) brightness = PercentType(str(levels.get("brightness", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"]["default_levels"][trigger_type][lux_type]["brightness"]))) #LOG.warn(u"light_action: trigger_type: {}, item.name: {}, item.state: {}, lux: {}, lux_trigger: {}, lux_type: {}, brightness: {}, lux_item_name: {}".format(trigger_type, item.name, item.state, items[AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"]["lux_item_name"]], lux_trigger, lux_type, brightness, lux_item_name)) if item.type in ["Dimmer", "Rollershutter"] or (item.type == "Group" and item.baseItem.type == "Dimmer"): if item.state != brightness: if item.state <= PercentType(DISABLE_AUTOMATION_BRIGHTNESS): events.sendCommand(item, brightness) LOG.info(u"{} {}: {}".format("<<<<<<<<<<<<<<<<<<<<<" if brightness == DecimalType(0) else ">>>>>>>", item.name, brightness)) else: LOG.info(u"'{}': dimmer is currently set > {}, so not adjusting".format(DISABLE_AUTOMATION_BRIGHTNESS, item.name)) else: LOG.debug(u"'{}': dimmer is already set to '{}', so not sending command".format(item.name, brightness)) elif item.type == "Color" or (item.type == "Group" and item.baseItem.type == "Color"): hue = DecimalType(str(levels.get("hue", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"]["default_levels"][trigger_type][lux_type]["hue"]))) saturation = PercentType(str(levels.get("saturation", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION["light_action"]["default_levels"][trigger_type][lux_type]["saturation"]))) if item.state != HSBType(hue, saturation, brightness): if item.state.brightness < PercentType(DISABLE_AUTOMATION_BRIGHTNESS): events.sendCommand(item, HSBType(hue, saturation, brightness)) LOG.info(u"{} {}: '{}'".format("<<<<<<<<<<<<<<<<<<<<<" if brightness == DecimalType(0) else ">>>>>>>", item.name, HSBType(hue, saturation, brightness))) else: LOG.info(u"'{}': brightness is currently set > {}, so not adjusting".format(DISABLE_AUTOMATION_BRIGHTNESS, item.name)) else: LOG.debug(u"'{}': color is already set to [{}, {}, {}], so not sending command".format(item.name, hue, saturation, brightness)) elif item.type == "Switch" or (item.type == "Group" and item.baseItem.type == "Switch"): new_state = brightness.as(OnOffType) if item.state != new_state: events.sendCommand(item, new_state) LOG.info(u"{} {}: {}".format("<<<<<<<<<<<<<<<<<<<<<" if new_state == OFF else ">>>>>>>", item.name, new_state)) else: LOG.debug(u"'{}': switch is already '{}', so not sending command".format(item.name, new_state))
def start_action(item, active, function_name): """ This is the function called by the rule to begin the selected action, which may be first passed through a timer. Args: item Item: The Item to perform the action on active bool: Area activity (True for active and False for inactive) function_name str: Name of the action function """ #start_time = DateTime.now().getMillis() timer_type = "active" if active else "inactive" function = globals()[function_name] function_metadata = get_key_value(item.name, "area_triggers_and_actions", function_name) limited = function_metadata.get("limited") timer_metadata = function_metadata.get(timer_type, {}) if timer_metadata or not limited: # this works since the states are binary timer_delay = timer_metadata.get("delay") if not timer_delay: function(item, active) elif timers.get(item.name, {}).get( function_name, {}).get(timer_type) is None or not timers[ item.name][function_name][timer_type].isAlive( ): # if timer does not exist, create it recurring = timer_metadata.get("recurring") item_iterations = timer_metadata.get("iterations") if item_iterations is not None and item_iterations > 0: iterations.update({item.name: {timer_type: item_iterations}}) timers.update({ item.name: { function_name: { timer_type: Timer(timer_delay, _timer_function, [ item, active, function_name, timer_type, timer_delay, recurring, function ]) } } }) timers[item.name][function_name][timer_type].start() LOG.debug(u"{}: '{}' second {}{} {} timer has started{}".format( item.name, timer_delay, "recurring " if recurring else "", function_name, timer_type, ", repeating {} times".format(item_iterations) if item_iterations else "")) _cancel_timer(item.name, function_name, "inactive" if active else "active")
def start_action(item, active, function_name): """ This is the function called by the rule to begin the selected action, which may be first passed through a timer. Args: item Item: The Item to perform the action on active boolean: Area activity (True for active and False for inactive) function_name string: Name of the action function """ #start_time = DateTime.now().getMillis() timer_type = "ON" if active else "OFF" function = globals()[function_name] function_metadata = get_key_value(item.name, "area_triggers_and_actions", "actions", function_name) limited = function_metadata.get("limited") timer_metadata = function_metadata.get(timer_type, {}) if not limited or timer_metadata: timer_delay = timer_metadata.get("delay") recurring = timer_metadata.get("recurring") #log.warn("start_action: item.name [{}], active [{}], function_name [{}], timer_type [{}], timer_delay [{}], recurring [{}], function [{}]".format(item.name, active, function_name, timer_type, timer_delay, recurring, function)) if not timer_delay: function(item, active) elif timer_dict.get(item.name, {}).get( function_name, {}).get(timer_type) is None or not timer_dict[ item.name][function_name][timer_type].isAlive( ): # if timer does not exist, create it timer_dict.update({ item.name: { function_name: { timer_type: Timer(timer_delay, _timer_function, [ item, active, function_name, timer_type, timer_delay, recurring, function ]) } } }) timer_dict[item.name][function_name][timer_type].start() log.debug("{}: [{}] second {}{} {} timer has started".format( item.name, timer_delay, "recurring " if recurring else "", function_name, timer_type)) stop_timer(item.name, function_name, "OFF" if active else "ON")
def mode_or_lux_change(event): """ This rule iterates through all triggering groups and replays all actions for groups that are currently active, using the current mode and lux level. """ #start_time = DateTime.now().getMillis() mode_change_or_system_start = (event.itemName == MODE_ITEM) if event is not None else True # get a list of active trigger groups (or all of them, if system started) for trigger_group in [group for group in itemRegistry.getItem("gArea_Trigger").members]: trigger_type = "active" if trigger_group.state in [ON, OPEN] else "inactive" action_groups = itemRegistry.getItems(trigger_group.name.replace("_Trigger", "_Action")) if action_groups: for action_group in action_groups:# there should be only 1 or None for item in action_group.members: item_metadata = get_metadata(item.name, "area_triggers_and_actions") action_function_names = item_metadata.configuration.keys() if item_metadata else [DEFAULT_ACTION_FUNCTION] if DEFAULT_ACTION_FUNCTION in action_function_names: light_action_metadata = get_key_value(item.name, "area_triggers_and_actions", DEFAULT_ACTION_FUNCTION) lux_item_name = light_action_metadata.get("lux_item_name", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION.get(DEFAULT_ACTION_FUNCTION, {}).get("lux_item_name")) if mode_change_or_system_start: start_new_thread(start_action, (item, trigger_group.state in [ON, OPEN], DEFAULT_ACTION_FUNCTION)) mode_or_lux_change.log.debug(u"Mode change or System start light adjustment: {}: {}: {}".format(items[MODE_ITEM], action_group.name, item.name)) else: if lux_item_name == event.itemName and not isinstance(event.itemState, UnDefType): # the lux Item associated with the action Item has changed state lux_current = event.itemState.intValue() lux_previous = event.oldItemState.intValue() elif lux_item_name is not None and lux_item_name == AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION.get(DEFAULT_ACTION_FUNCTION, {}).get("lux_item_name") and not isinstance(items[lux_item_name], UnDefType): # this action Item is associated to the default lux Item lux_current = items[lux_item_name].intValue() lux_previous = PersistenceExtensions.previousState(itemRegistry.getItem(lux_item_name), True).state.intValue() else: # this action Item is not associated to a lux Item and there is no default lux_item_name configured in AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION break lux_trigger = light_action_metadata.get(trigger_type, {}).get("modes", {}).get(items[MODE_ITEM].toString(), {}).get("lux_trigger", AREA_TRIGGERS_AND_ACTIONS_CONFIGURATION[DEFAULT_ACTION_FUNCTION]["default_levels"][trigger_type]["lux_trigger"]) if min(lux_previous, lux_current) < lux_trigger < max(lux_previous, lux_current): start_new_thread(start_action, (item, trigger_group.state in [ON, OPEN], DEFAULT_ACTION_FUNCTION)) mode_or_lux_change.log.debug(u"Lux change light adjustment: {}: {}: current: '{}', previous: '{}'".format(action_group.name, item.name, lux_current, lux_previous))
def battery_check(event): """monitors battery charge state""" low_battery_threshold = 20 def is_battery_low(item, threshold): if isinstance(item.state, OnOffType): if item.state == "ON": LogInfo("{} Batterie Warnung ist ON".format(item.name), battery_check.log) return True elif isinstance(item.state, DecimalType): if item.state < DecimalType(low_battery_threshold): SendInfo("{} hat Charge Level {} < {}".format(item.name, item.state, threshold), battery_check.log) return True # elif isinstance(item.state, UnDefType): # SendWarning("{} ist UNDEF".format(item.name), battery_check.log) # SendInfo("noch voll, Batterie Charge Level ist {} >= {}".format(item.state, threshold), battery_check.log) return False battery_low = filter(lambda item: is_battery_low(item, low_battery_threshold), ir.getItem("Batterien").members) # if len(battery_low) == 0: # SendInfo("Kein Batterieladestand unter der Meldegrenze ({} %)".format(str(low_battery_threshold)), battery_check.log) # return battery_msg = "Batterieladestand unter der Meldegrenze : {}".format(", ".join(map(lambda sensor: "{}={}".format((get_key_value(sensor.name, "Static", "name") or sensor.name), sensor.state), sorted(sensor for sensor in battery_low)))) telegram = actions.get("telegram", "telegram:telegramBot:openhab") # telegram.sendTelegram(markus_telegram_chatid, battery_msg) # log.debug("dir(log)=[{}]".format(dir(log))) # SendInfo(battery_msg, battery_check.log) SendInfo(battery_msg)
def light_action(item, active): """ This function performs an action on a light Item. When called, this function pulls in the metadata for the supplied Item or uses the default values specified in ``configuration.area_triggers_and_actions_dict"["default_levels"]``, if the metadata does not exist. This metadata is then compared to the current lux level to determine if a light should be turned OFF or set to the specified level. This function should work for everyone without modification. Args: Item item: The Item to perform the action on boolean active: Area activity (True for active and False for inactive) """ #start_time = DateTime.now().getMillis() item_metadata = get_key_value(item.name, "area_triggers_and_actions", "modes", str(items["Mode"])) low_lux_trigger = item_metadata.get( "low_lux_trigger", area_triggers_and_actions_dict["default_levels"]["low_lux_trigger"]) hue = DecimalType( item_metadata.get( "hue", area_triggers_and_actions_dict["default_levels"]["hue"])) saturation = PercentType( str( item_metadata.get( "saturation", area_triggers_and_actions_dict["default_levels"] ["saturation"]))) brightness = PercentType( str( item_metadata.get( "brightness", area_triggers_and_actions_dict["default_levels"] ["brightness"]))) #log.warn("light_action: item.name [{}], active [{}], brightness [{}], lux [{}], low_lux_trigger [{}]".format(item.name, active, brightness, items[area_triggers_and_actions_dict["lux_item_name"]], low_lux_trigger)) lux_item_name = area_triggers_and_actions_dict.get("lux_item_name") if active and brightness > PercentType(0) and ( True if lux_item_name is None else items[lux_item_name].intValue() <= low_lux_trigger): if item.type == "Dimmer" or (item.type == "Group" and item.baseItem.type == "Dimmer"): if item.state != brightness: if item.state < PercentType(99): events.sendCommand(item, brightness) log.info(">>>>>>> {}: {}".format(item.name, brightness)) else: log.info( "[{}]: dimmer was manually set > 98, so not adjusting". format(item.name)) else: log.debug( "[{}]: dimmer is already set to [{}], so not sending command" .format(item.name, brightness)) elif item.type == "Color" or (item.type == "Group" and item.baseType == "Color"): if item.state != HSBType(hue, saturation, brightness): if item.state.brightness < PercentType(99): events.sendCommand(item, HSBType(hue, saturation, brightness)) log.info(">>>>>>> {}: [{}]".format( item.name, HSBType(hue, saturation, brightness))) else: log.info( "[{}]: brightness was manually set > 98, so not adjusting" .format(item.name)) else: log.debug( "[{}]: color is already set to [{}, {}, {}], so not sending command" .format(item.name, hue, saturation, brightness)) elif item.type == "Switch" or (item.type == "Group" and item.baseItem.type == "Switch"): if item.state == OFF: events.sendCommand(item, ON) log.info(">>>>>>> {}: ON".format(item.name)) else: log.debug( "[{}]: switch is already [ON], so not sending command". format(item.name)) else: if item.type == "Dimmer" or (item.type == "Group" and item.baseItem.type == "Dimmer"): if item.state != PercentType(0): if item.state < PercentType(99): events.sendCommand(item, PercentType(0)) log.info("<<<<<<<<<<<<<<<<<<<<< {}: 0".format(item.name)) else: log.info( "{}: dimmer was manually set > 98, so not adjusting". format(item.name)) else: log.debug( "[{}]: dimmer is already set to [0], so not sending command" .format(item.name)) elif item.type == "Color" or (item.type == "Group" and item.baseType == "Color"): if item.state != HSBType(DecimalType(0), PercentType(0), PercentType(0)): if item.state.brightness < PercentType(99): events.sendCommand(item, "0, 0, 0") log.info("<<<<<<<<<<<<<<<<<<<<< {}: [0, 0, 0]".format( item.name)) else: log.info( "{}: brightness was manually set > 98, so not adjusting" .format(item.name)) else: log.debug( "[{}]: color is already set to [0, 0, 0], so not sending command" .format(item.name)) elif item.type == "Switch" or (item.type == "Group" and item.baseItem.type == "Switch"): if item.state == ON: events.sendCommand(item, OFF) log.info("<<<<<<<<<<<<<<<<<<<<< {}: OFF".format(item.name)) else: log.debug( "[{}]: switch is already set to [OFF], so not sending command" .format(item.name))
def types(type): return [ i for i in items if get_key_value(i, NAMESPACE, "type") == type ]
def generated_triggers(function): lux_item_names = list(set([get_key_value(item.name, "area_triggers_and_actions", DEFAULT_ACTION_FUNCTION, "lux_item_name") for item in itemRegistry.getAll() if get_key_value(item.name, "area_triggers_and_actions", "light_action", "lux_item_name")])) for lux_item_name in lux_item_names: when("Item {} changed".format(lux_item_name))(function) return function