Dear community,
I try to create a class for a library module, that gets a configuration passed in and creates rules to call class methods.
As a starting point and for easier presentation in this post, ExampleClass
is still in a script file, gets the name of an item and creates two rules that trigger on an ItemStateUpdateTrigger
on this single item.
The event is passed to the class methods and I expected that these can use event.itemState
, event.itemName
and other methods described in the openhab-helper-libraries documentation.
A dir()
on the passed-in object shows different attributes.
Here is the script file:
# jython imports
import time
import uuid
# openhab2 jsr223 imports
import core.items
from core.jsr223.scope import events
from core.log import logging, LOG_PREFIX
from core.triggers import ItemStateUpdateTrigger
from core.utils import getItemValue
scriptExtension.importPreset("RuleSupport")
scriptExtension.importPreset("RuleSimple")
module_name = "generic_rule_example_1"
module_prefix = module_name + "_"
log = logging.getLogger("{}.{}".format(LOG_PREFIX, module_name))
RESPONSE_TIME = 3
'''the time tests are waiting between their actions and
checking results.
'''
class RuleTemplate(SimpleRule):
def __init__(self, triggers, f):
self.setTriggers(triggers)
self.function = f
def execute(self, module, input):
try:
self.function(input)
except:
log.error(traceback.format_exc())
class ExampleClass(object):
def __init__(self, item):
self.rule1 = automationManager.addRule(RuleTemplate([ItemStateUpdateTrigger(item.name).trigger], self.method_a))
self.rule2 = automationManager.addRule(RuleTemplate([ItemStateUpdateTrigger(item.name).trigger], self.method_b))
def method_a(self, event):
log.info("ExampleClass.method_a()")
log.debug("event: {})".format(event))
log.debug("dir(event): {}".format(dir(event)))
#
log.debug("event.keys: {})".format(event.keys()))
log.debug("dir(event.items): {}".format(dir(event.items)))
def method_b(self, event):
log.info("ExampleClass.method_b()")
def cleanup(self):
automationManager.removeHandler(self.rule1.UID)
automationManager.removeHandler(self.rule2.UID)
def scriptLoaded(id):
ITEM1NAME = "TestSwitch1"
item1 = core.items.add_item(ITEM1NAME, "Switch")
exampleObject = ExampleClass(item1)
log.info("example object created.")
try:
time.sleep(RESPONSE_TIME)
value = OFF if getItemValue(item1, OFF) != OFF else ON
log.info("postUpdate({}, {})".format(item1.name, value))
events.postUpdate(item1, value)
time.sleep(RESPONSE_TIME)
exampleObject.cleanup()
except Exception:
log.error("exception running example")
log.exception("message")
core.items.remove_item(item1)
def scriptUnloaded():
# this executes automatically when the script is unloaded/reloaded. if you create any threads or timers, make sure you cancel/stop them here!
log.info("script cleanup")
And the log output including dir()
output:
07:08:18.801 [INFO ] [ort.internal.loader.ScriptFileWatcher] - Loading script 'python/personal/generic_rule_example_1.py'
07:08:18.830 [DEBUG] [jsr223.jython.core.items ] - Item added: [TestSwitch1 (Type=SwitchItem, State=NULL, Label=null, Category=null)]
07:08:18.835 [DEBUG] [ipse.smarthome.automation.module.core] - ServiceEvent REGISTERED - {org.eclipse.smarthome.core.events.EventSubscriber}={service.id=945, service.bundleid=214, service.scope=singleton, event.topics=smarthome/items/TestSwitch1/*} - org.eclipse.smarthome.automation.module.core
07:08:18.839 [DEBUG] [ipse.smarthome.automation.module.core] - ServiceEvent REGISTERED - {org.eclipse.smarthome.core.events.EventSubscriber}={service.id=946, service.bundleid=214, service.scope=singleton, event.topics=smarthome/items/TestSwitch1/*} - org.eclipse.smarthome.automation.module.core
07:08:18.842 [INFO ] [jsr223.jython.generic_rule_example_1 ] - example object created.
07:08:21.847 [INFO ] [jsr223.jython.generic_rule_example_1 ] - postUpdate(TestSwitch1, ON)
07:08:21.850 [DEBUG] [tomation.core.internal.RuleEngineImpl] - The trigger 'bb274100a2d011e988629506815ad68e' of rule '7602490d-7bfd-44cb-a06d-2884e73ce8ff' is triggered.
07:08:21.852 [DEBUG] [tomation.core.internal.RuleEngineImpl] - The trigger 'bb28044fa2d011e9ab5c9506815ad68e' of rule '6beb94e7-55f4-4916-9ce1-b640984240c1' is triggered.
07:08:21.859 [INFO ] [jsr223.jython.generic_rule_example_1 ] - ExampleClass.method_b()
07:08:21.861 [DEBUG] [tomation.core.internal.RuleEngineImpl] - The rule '6beb94e7-55f4-4916-9ce1-b640984240c1' is executed.
07:08:21.862 [INFO ] [jsr223.jython.generic_rule_example_1 ] - ExampleClass.method_a()
07:08:21.866 [DEBUG] [jsr223.jython.generic_rule_example_1 ] - event: {state: ON, bb274100a2d011e988629506815ad68e.state: ON, event: TestSwitch1 updated to ON, bb274100a2d011e988629506815ad68e.event: TestSwitch1 updated to ON, module: bb274100a2d011e988629506815ad68e})
07:08:21.870 [DEBUG] [jsr223.jython.generic_rule_example_1 ] - dir(event): ['Entry', 'SimpleEntry', 'SimpleImmutableEntry', '__class__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', '__subclasshook__', '__unicode__', 'class', 'clear', 'clone', 'compute', 'computeIfAbsent', 'computeIfPresent', 'containsKey', 'containsValue', 'copy', 'empty', 'entrySet', 'equals', 'forEach', 'fromkeys', 'get', 'getClass', 'getOrDefault', 'has_key', 'hashCode', 'isEmpty', 'items', 'iteritems', 'keySet', 'keys', 'merge', 'notify', 'notifyAll', 'pop', 'popitem', 'put', 'putAll', 'putIfAbsent', 'remove', 'replace', 'replaceAll', 'setdefault', 'size', 'toString', 'update', 'values', 'wait']
07:08:21.873 [DEBUG] [jsr223.jython.generic_rule_example_1 ] - event.keys: [u'state', u'bb274100a2d011e988629506815ad68e.state', u'event', u'bb274100a2d011e988629506815ad68e.event', u'module'])
07:08:21.876 [DEBUG] [jsr223.jython.generic_rule_example_1 ] - dir(event.items): ['__call__', '__class__', '__delattr__', '__doc__', '__ensure_finalizer__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__str__', '__subclasshook__']
07:08:21.878 [DEBUG] [tomation.core.internal.RuleEngineImpl] - The rule '7602490d-7bfd-44cb-a06d-2884e73ce8ff' is executed.
07:08:24.857 [DEBUG] [jsr223.jython.core.items ] - Item removed: [TestSwitch1]
07:08:24.859 [DEBUG] [ort.internal.loader.ScriptFileWatcher] - Script loaded: python/personal/generic_rule_example_1.py
I appreciate any hint on this, including a different approach without the use of the extra class RuleTemplate
.