Jython helper libraries for OH3

I think for the purpose of triggers.py isValidExpression, I’ll just implement a simple regex check. Hopefully I’ll manage to fork and publish my modifications on github some time today so others can use it to get their jython rules up and running again, while waiting for @5iver to publish the official update.

1 Like

I think having some working helper libraries for OH3 will make many Jython users very happy! :slight_smile: :+1:

2 Likes

I’ve updated the original post with the link to my patched version.

2 Likes

Seems to work pretty well!
Thank You for sharing!

Thanks! Do you have any reference for ZonedDateTime classes? I need to rewrite a few rules which are still using JodaTime

Did you mean something like this?
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZonedDateTime.html

Changing from Joda to ZonedDateTime seems straight forward:

  • from org.joda.time import DateTimefrom java.time import ZonedDateTime
  • DateTime.now()ZonedDateTime.now()
  • .getHourOfDay().getHour()
  • .getMinuteOfHour().getMinute()
  • .plusMillis(x) → '.plusNanos(x * 1000000)`

and so on.

Alternatively, for even less change:

from java.time import ZonedDateTime as DateTime

Then you just need to change getHourOfDay etc to their equivalent methods of ZonedDateTime. Most of the other methods have the same name, e.g. plusMinutes().

2 Likes

I detected another issue with the triggers: StartupTrigger is not working properly. By modifing the StartupTrigger class (around line 720 in triggers.py) I got it working:

Replace
self.trigger = TriggerBuilder.create().withId(trigger_name).withTypeUID("jsr223.StartupTrigger").withConfiguration(Configuration()).build()

with

self.trigger = TriggerBuilder.create().withId(trigger_name).withTypeUID(“core.SystemStartlevelTrigger”).withConfiguration(Configuration({
“startlevel”: “100”
})).build()

Thanks for the nice working version of this. But why don’t you open a PR for this to the official repo?

Thank you. I have updated my version on github too.

I am unsure whether an official fix may have already been prepared but not yet uploaded. It is also not quite polished. I commented out some things instead of removing them, and my replacement implementation is just a quick and dirty solution. I’d be happy to submit it as a PR if Scott wanted it.

Thanks, yes I found them later on. It was not that easy to migrate everything from these deprecated libs.

Right now it seems that most of my rules are working… Only executeCommandLines seems to have problems, even with the new parameter list.

Also it seems for me that System started triggers won’t fire on system startup. Is this possible?

See above. I’ve pushed a new update that should fix the startup trigger, thanks to @pail_frank23
The only change was to triggers.py

I already have that triggers.py, but I will re-check it…

Yes I have that one and still not working…

Hmmm, strange. My @when(“System started”) rules were working prior to applying the changes suggested by @pail_frank23. The changes suggested by @pail_frank23 actually caused my “System started” rules not to fire.

I have setup a test system and as far as I can remember, I had some error in the beggining about StartupTrigger, but after StartupTriggers worked. I will try to rollback to the old triggers.py and try again…

Try this version (the one right before “fixing” the startup trigger)
https://raw.githubusercontent.com/jimtng/openhab-helper-libraries/31da60805dd03b5e199e041e47274a4f1521144d/Core/automation/lib/python/core/triggers.py

Yes this seems to work, thanks!

One last thing which is not working for me regarding Jython rules is executeCommandLine. Did you get this working? I can’t really get any useful info why it is not working. I have changed the parameters as suggested in docs and other posts, but none of them worked. Basically it returns instantly with ‘None’, not even waiting for the timeout.

I was able to solve it. Basically you need to pass every command line argument as a seperate argument for executeCommandLine.

I have reverted the StartupRule trigger for the time being. I don’t quote understand why the old one worked and the new one doesn’t. It seems that the new one should be the one that works.

This works for me:

class StartupTrigger(Trigger):
    """
    This class builds a StartupTrigger Module to be used when creating a Rule.

    See :ref:`Guides/Rules:Extensions` for examples of how to use these extensions.

    Examples:
        .. code-block::

            MyRule.triggers = [StartupTrigger().trigger]

    Args:
        trigger_name (string): (optional) name of this trigger

    Attributes:
        trigger (Trigger): Trigger object to be added to a Rule
    """
    def __init__(self, trigger_name=None):
        trigger_name = validate_uid(trigger_name)
        self.trigger = TriggerBuilder.create().withId(trigger_name).withTypeUID("jsr223.StartupTrigger").withConfiguration(Configuration()).build()

This seems like it should work instead, but it doesn’t

class StartupTrigger(Trigger):
    """
    This class builds a StartupTrigger Module to be used when creating a Rule.

    See :ref:`Guides/Rules:Extensions` for examples of how to use these extensions.

    Examples:
        .. code-block::

            MyRule.triggers = [StartupTrigger().trigger]

    Args:
        trigger_name (string): (optional) name of this trigger

    Attributes:
        trigger (Trigger): Trigger object to be added to a Rule
    """
    def __init__(self, trigger_name=None):
        trigger_name = validate_uid(trigger_name)
        self.trigger = (
            TriggerBuilder.create()
            .withId(trigger_name)
            .withTypeUID("core.SystemStartlevelTrigger")
            .withConfiguration(Configuration({"startlevel": "100"}))
            .build()
        )

I’m not sure how executeCommandLine would be related to jython, especially the helper libraries, but for the benefit of others who might come across the same issue, could you post your code both before and after?