In your example you need it because you have multiple items able to trigger the rule and you are using the received update
trigger, that is far less common. I have some rules that I want to fire every time the device provides a status update, so that I can make sure it is set to the value the automation wants it to be at. I don’t think your rule needs to use received update
, I think changed
would be enough. changed
fires after the item state has been updated, so you don’t have a race between your rule and the event update code in openHAB.
That is not what this is, the received update
and changed
triggers work in different ways, as intended. The received update
trigger fires when an item state update event is put on the event bus. The changed
trigger fires after the aforementioned update event is processed and the update changed the state. Often changed
is the more appropriate trigger to use. This is not a case of “by design” it works this way so that’s it, this is “by design” both triggers are available because they are different and each have their use case.
In hopes of helping you along your openHAB/Python learning curve, I took your script in the first post and rewrote it. I have switch over to the easier way to do logging, sending commands, and getting item states. I have also demonstrated a more readable way to get the most relevant item state. And I have also changed some of your conditionals to be more Pythonic. Contrary to my above suggestion that changed
might be a more appropriate trigger, I have left it as received update
because I don’t know what your exact use case is. Also to demonstrate in case you ever need to use received update
, because there may be cases where you need the rule to run even if the item state did not changed, at which time it’s up to you to get the most relevant item state as required by your code.
from core.rules import rule
from core.triggers import when
"""
from org.slf4j import LoggerFactory
def logprint(text):
pass
LoggerFactory.getLogger("org.eclipse.smarthome.automation.examples").info(text)
"""
from core.log import logging, LOG_PREFIX
log = logging.getLogger("{}.nightlights".format(LOG_PREFIX))
"""
@rule("Sunset Rule", description="", tags=["schedule"])
@when("Channel \"astro:sun:local:civilDusk#event\" triggered START")
def Sunset_Decorators(event):
item=ir.getItem("DarkOutside")
item.send(ON)
Use events.sendCommmand("string", "string")
"""
@rule("Sunset Rule", tags=["schedule"])
@when("Channel astro:sun:local:civilDusk#event triggered START")
def Sunset_Decorators(event):
events.sendCommand("DarkOutside", "ON")
@rule("Sunrise Rule", description="", tags=["schedule"])
@when("Channel \"astro:sun:local:civilDawn#event\" triggered START")
def Sunrise_Decorators(event):
events.sendCommand("DarkOutside", "OFF")
@rule("Night Lights", tags=["schedule"])
@when("Item DarkOutside received update")
@when("Item SleepMode received update")
def NightLights_Decorators(event):
"""
isDarkOutside=1 if itemDarkOutside.getState() == ON else 0
isSleepMode=1 if itemSleepMode.getState() == ON else 0
Don't cache the item, use True/False
"""
isDarkOutside = True if ir.getItem("DarkOutside").getState() == ON else False
isSleepMode = True if ir.getItem("SleepMode").getState() == ON else False
if event.itemName == "DarkOutside":
isDarkOutside = True if event.itemState == ON else False
else:
isSleepMode = True if event.itemState == ON else False
"""
logprint("dark: " + str(isDarkOutside) + " sleep: " + str(isSleepMode))
string.format is your friend, you can even use names for the fields to replace
"""
log.info("dark: {dark} sleep: {sleep}".format(
dark=isDarkOutside,
sleep=isSleepMode
))
# in Python you can 'if var' to check 'if var == True'
events.sendCommand("NightLights", "ON" if isDarkOutside else "OFF")
events.sendCommand("MainGateLights_On", "ON" if isDarkOutside and not isSleepMode else "OFF")
itemMainGateLights=ir.getItem("MainGateLights_On")
itemMainGateLights.send(ON if isDarkOutside!=0 and isSleepMode==0 else OFF)