Hello i hope you guys can help me. I am trying to define and import my own modules.
Therfore i created the file $ohdir/lib/python/openhab/timer.py with the followng content:
and i am able to create an object where the type() returns the correct type. But the problem ist that my own methods (e.g. remaining()) do not work. If i however define the class MyTimer in the script itself it works like a charm. What is wrong with importing my class from a library?
My seconds issue presumably has the same root cause. I would like to define a global dictionary, which i can access from every script
In Python, âglobalâ variables are scoped to a module. If you create a module and expose your dictionary though a âglobalâ variable in the module, you can then import that module into multiple scripts.
For your timer example, what is threading._Timer (with the underscore) vs. threading.Timer?
Thanks the import of a dictionary works like you said
threading.Timer is a function and threading._Timer is a class which MyTimer inherits from. My function basically does the same as threading.Timer but has a .remaining() and .elapsed() method which returns a time in seconds
Interesting. I didnât realize Timer was a function (never tried to subclass it). Importing classes from modules is not a problem in general. However, I donât understand what youâre doing with the _Timer subclass. It appears you are not invoking the _Timer constructor which has required arguments. How does that work?
Hi steve thanks again for your help. It actually works now (with the class like I posted above) but i have to
import threading, time
in my script which is strange imo, because it is imported in the module.
It would have been easy to identify if i would be able to see the error messages the script is throwing.
Is there a way to display them all, like a was in a python shell? Now I am debugging with a lot of logging statements, which is very annoying
Currently I am observing the same error âNameError: name âSimpleRuleâ is not defined in at line number xyâ as described above when openHAB is started. When touching the file at a later time it is loaded without an issue.
Itâs not built-in. Even the new SmartHome rule engine doesnât support it, AFAIK. Iâm guessing the reason it wasnât officially supported with the new engine is because there is no well-defined âsystem startedâ event and so the trigger has always been a bit dubious. Itâs possible to write your own custom trigger to do something similar. I created one in my openhab2-jython GitHub repo. In this case, âSystem Startedâ was really âRule Definedâ.
Iâm not currently in a position to try it myself, but Iâd recommend trying ruleRegistry.remove(ruleInstance.uid). You can also look at the source code (especially the documentation) for the RuleRegistryImpl class.
Sorry I am not a very skilled programmer, I hope you can guide me on how to use your custom trigger. How would my class look like? If i do it like this it complains about a missing handler:
scriptExtension.importPreset("RuleSupport")
scriptExtension.importPreset("RuleSimple")
from openhab.triggers import StartupTrigger
class MyRule(SimpleRule):
def __init__(self):
self.triggers = [
Trigger("SystemStartedTrigger", "openhab.triggers.StartupTrigger",
Configuration())
]
def execute(self, module, input):
# some code
automationManager.addRule(MyRule())
From your source code i assume i need an âopenhab.STARTUP_MODULE_IDâ, but where do i get it from?
Everytime a rule gets loaded it gets a new random id. Is it possible to define an own rule id beforehand? I assume that would also help me to delete a specific rule as asked in my 2nd question.
Is âTestCaseRunnerâ the rule name or the UID? About the scope, you may be right. There are a few scope objects that are created for each script. I think that the automation manager and rule registry are two of those.
Yes, âTestCaseRunnerâ is the UID of a rule created in another script.
You can see that enable/disbable on the rule works but not the remove.
How could I remove a rule declared in another script?
2018-02-13 19:53:28.936 [thome.event.RuleAddedEvent] - Rule 'TestCaseRunner' has been added.
The setEnabled solves my question 2. To get run the rule once its activated (question 1) i tried the runNow method, where the log tells me that the rule is started, but the execute block does not seem to be executed since the log is missing my logging line.
From the source code, it appears that the automationManager does some adaptation to the registered rule for scripting purposes. Adding the rule directly to the ruleRegistry may have been the original issue. Grabbing the last registered rule will work most of the time but it also may fail nondeterministically since the registry could be updated from other threads and the most recent rule may not be the one you want.