Hi there,
I created a nice and easy library for jython which makes creating rules even more easier.
It would be really nice to get some feedback and I think this may be useful for other people, too.
So check it out at
Any feedback is apreciated!
Full credit to @steve1 who came up with all this billiant stuff!!
What does it do:
- Creating an Instance of a rule is enough:
#create an instance of the rule
#Note: this is different! Creating an instance is enough!
MyJSR223RuleName()
- It prints all the added rules in the logger window. This makes searching for errors really easy.
+--------------------------------------------------------------------------------+
| Adding Rules: |
| - Rule1 |
| - Rule2 |
| - Rule3 |
+--------------------------------------------------------------------------------+
- It checks whether you have defined valid rule triggers:
+--------------------------------------------------------------------------------+
| Checking Rule1: |
| - Found item 'MyItem1' for ChangedEventTrigger |
| - Could not find item 'NonexistingItem1' for ChangedEventTrigger |
| Rule 'Rule1' is not OK! |
+--------------------------------------------------------------------------------+
| Checking Rule2: |
| - Found item 'MyItem2' for ChangedEventTrigger |
| Rule 'Rule2' is OK! |
+--------------------------------------------------------------------------------+
| Checking Rule3: |
| - Found item MyItem3 for UpdatedEventTrigger |
| Rule 'Rule3' is OK! |
+--------------------------------------------------------------------------------+
- It adds a new Initialize() - function to the rule-class:
def Initialize(self):
#initialize all your variables and required states here
self.__myvariable = 0
It can be linked to a specific item so setting openhab to a defined state (like after startup) is really easy.
SimpleRules:
#Easy ItemChanged - Rule declaration.
@EasyRule.ItemChanged("Itemname")
def MyRule1():
BusEvent.postUpdate("Itemname", "0")
#no need to use oh-vars for the trigger anymore:
@EasyRule.ItemChanged("NumberItem", None, 1)
def MyRule1Changed():
BusEvent.postUpdate("NumberItem", "0")
#Easy ItemUpdated- Rule declaration.
@EasyRule.ItemUpdated("Itemname")
def MyRule2():
BusEvent.postUpdate("Itemname", "0")
#Easy TimerTrigger- Rule declaration.
@EasyRule.TimerTrigger("Chron")
def MyRule3():
BusEvent.postUpdate("Itemname", "0")
Works also with the event-item:
#Accessing the event-item is also possible:
@EasyRule.ItemChanged("TestString")
def MyRule1(event):
print(event)
#Easy ItemUpdated- Rule declaration.
@EasyRule.ItemUpdated("TestString")
def MyRule2(event):
print(event)
The variables of the event get automatically converted to the jython equivalent (DecimalType -> int/float, DateTime to float, StringType -> str). Accessing the original item is still possible. The above two rules produce the following output:
Event [triggerType=CHANGE, item=TestString (Type=StringItem, State=ON, ohitem=(...)), oldState=OFF, newState=ON, command=None, ohEvent=(...)]
Event [triggerType=UPDATE, item=TestString (Type=StringItem, State=ON, ohitem=(...)), oldState=None, newState=ON, command=None, ohEvent=(...)]
Custom Exception-Handler are also possible:
These will push all errors via pushover.
def PushToPushover(Rule, exception):
pushover = oh.getAction("Pushover")
tb = traceback.format_exc()
#try slicing - this is just to make it look pretty
searchstr = "return cls.execute(self, Event(event) if self.ProcessEvents else event)"
len_seach = len(searchstr)
pos = tb.rfind(searchstr)
if pos != -1:
tb = tb[-1 * len(tb) + pos + len_seach:]
pushover.pushover("Error in '{}':\n'{}'\n\n{}".format(Rule.name, exception, tb[-400:].strip(), 1))
EasyRule.SetExceptionHandler(PushToPushover)
Creating complex rule is more convenient, too:
@EasyRule.Rule
class cContact:
#no need to call the base-class
def __init__(self, item_name):
self.__trigger_item = item_name
self.__counter_item = cContact.__item_alias[item_name]
#convenient initializer function
def Initialize(self):
print( "This function still gets called when the rule is loaded or the init-item changes to ON")
def execute(self, event):
#the event has the converted variables, too.
myfloatvar = event.item.state
#per Rule logger is automatically available
self.logger.warning("asdfasdf")