_DirectoryEventTriggerHandlerFactory doesn't work
hemagi opened this issue · 3 comments
Describe the bug
The _DirectoryEventTriggerHandlerFactory in 100_DirectoryTrigger.py and therefore the DirectoryEventTrigger doesn't work at all and, after fix, does not provide the necessary information in the event.
To Reproduce
In a module I defined a helper class with some triggers, i.e.
from core.triggers import DirectoryEventTrigger
from core.jsr223.scope import SimpleRule
...
class OwnRule(SimpleRule):
def watch_directory(self,path):
self.triggers.append(DirectoryEventTrigger(path).trigger)
...
Using this trigger and after adding a file to the watched directory one gets:
2020-07-31 09:13:03.932 [ERROR] [ore.common.registry.AbstractRegistry] - Cannot inform the listener "org.openhab.core.automation.internal.RuleEngineImpl$2@30c355fe" about the "ADDED" event: NotImplementedError: 'Handler' object does not implement abstract method 'setCallback' from 'org.openhab.core.automation.handler.ModuleHandler'
org.python.core.PyException: NotImplementedError: 'Handler' object does not implement abstract method 'setCallback' from 'org.openhab.core.automation.handler.ModuleHandler'
at org.python.core.Py.NotImplementedError(Py.java:140) ~[?:2.7.2]
at org.python.compiler.ProxyCodeHelpers.notImplementedAbstractMethod(ProxyCodeHelpers.java:97) ~[?:2.7.2]
at org.python.proxies.__main__$Handler$1.setCallback(Unknown Source) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl.lambda$0(RuleEngineImpl.java:642) ~[?:?]
at java.util.ArrayList.forEach(ArrayList.java:1259) ~[?:1.8.0_262]
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1082) ~[?:1.8.0_262]
at org.openhab.core.automation.internal.RuleEngineImpl.register(RuleEngineImpl.java:639) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl.activateRule(RuleEngineImpl.java:856) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl.setRule(RuleEngineImpl.java:504) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl.addRule(RuleEngineImpl.java:464) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl$2.added(RuleEngineImpl.java:272) ~[?:?]
at org.openhab.core.automation.internal.RuleEngineImpl$2.added(RuleEngineImpl.java:1) ~[?:?]
...
I fixed this in 100_DirectoryTrigger.py by adding
def setCallback(self, callback):
self.rule_engine_callback = callback
to
class Handler(TriggerHandler):
@log_traceback
def __init__(self, trigger):
TriggerHandler.__init__(self)
self.rule_engine_callback = None
self.trigger = trigger
config = trigger.configuration
self.watcher = JythonDirectoryWatcher(
config.get('path'), eval(config.get('event_kinds')),
watch_subdirectories=config.get('watch_subdirectories'))
self.watcher.callback = self.handle_directory_event
self.watcher.activate()
def setRuleEngineCallback(self, rule_engine_callback):
self.rule_engine_callback = rule_engine_callback
(the latter method setRuleEngineCallback() was never called and should be removable).
After this one gets not the expected event, because only the 'event' entry is taken from the callback parameters.
Therefore I replaced
@log_traceback
def handle_directory_event(self, event, kind, path):
self.rule_engine_callback.triggered(self.trigger, {
'event': event,
'kind': kind,
'path': path
})
by
@log_traceback
def handle_directory_event(self, event, kind, path):
self.rule_engine_callback.triggered(self.trigger, {
'event': { 'kind': kind,
'path': path,
}
})
At the end the handler became
class _DirectoryEventTriggerHandlerFactory(TriggerHandlerFactory):
class Handler(TriggerHandler):
@log_traceback
def __init__(self, trigger):
TriggerHandler.__init__(self)
self.rule_engine_callback = None
self.trigger = trigger
config = trigger.configuration
self.watcher = JythonDirectoryWatcher(
config.get('path'), eval(config.get('event_kinds')),
watch_subdirectories=config.get('watch_subdirectories'))
self.watcher.callback = self.handle_directory_event
self.watcher.activate()
def setCallback(self, callback):
self.rule_engine_callback = callback
@log_traceback
def handle_directory_event(self, event, kind, path):
self.rule_engine_callback.triggered(self.trigger, {
'event': { 'kind': kind,
'path': path,
}
})
def dispose(self):
self.watcher.deactivate()
self.watcher = None
def get(self, trigger):
return _DirectoryEventTriggerHandlerFactory.Handler(trigger)
in order to work as expected.
Environment (please complete the following information):
- Jython version: jython-standalone-2.7.2.jar
- openHAB version: 2.5.7
I've stated several times here and in the forum that this has been broken, along with the OSGIEvent Trigger, since OH 2.4 S1319. I have an update with fixes and will compare them to what you have put together before I push. Thank you!
Potentially it is better to implement
@log_traceback
def handle_directory_event(self, event, kind, path):
self.rule_engine_callback.triggered(self.trigger, {
'event': { 'event' : event,
'kind': str(kind),
'path': str(path),
}
})
- Maybe someone is interested in the event itself
- The kind and path should be returned pythonic, not as Java objects