[SOLVED] First stab at Jython

My first (failed) attempt at Jython for a couple of rules. Help please. I am on 2.5M4

Item

Switch IsItDark <moon>

Script

from core.rules import rule
from core.triggers import when
from core.jsr223.scope import events

@rule("Jython IsItDark Sunset)", description="This triggers the IsItDark Switch based on sunset time")
@when("Channel astro:sun:local:set#event triggered START")
events.sendCommand(IsItDark, "ON")

@rule("Jython IsItDark Sunrise)", description="This triggers the IsItDark Switch based on sunrise time")
@when("Channel astro:sun:local:rise#event triggered START")
events.sendCommand(IsItDark, "OFF")

Error

2019-10-20 19:19:25.892 [INFO ] [me.core.service.AbstractWatchService] - Loading script 'python/personal/IsItDark.py'

2019-10-20 19:19:27.345 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab2/automation/jsr223/python/personal/IsItDark.py': SyntaxError: mismatched input 'events' expecting CLASS in <script> at line number 7 at column number 0

My Rules DSL

rule "Sunset"
when
    Channel 'astro:sun:local:set#event' triggered START
then
    IsItDark.postUpdate(ON)
end

rule "Sunrise"
when
    Channel 'astro:sun:local:rise#event' triggered START
then
    IsItDark.postUpdate(OFF)
end
1 Like

You need to define a function under the role decorators.

@when(blah blah blah)
def some_name(event):
    # rule code

You don’t need to import this in scripts, since ‘events’ is automatically imported for you in the default script scope.

What Rich said, with some consolidation…

from core.rules import rule
from core.triggers import when

@rule("Jython IsItDark)", description="This triggers the IsItDark Switch based on sunrise and sunset times")
@when("Channel astro:sun:local:set#event triggered START")
@when("Channel astro:sun:local:rise#event triggered START"
def is_it_dark(event):
    events.sendCommand(IsItDark, "ON" if "set" in str(event.channel).split(":") else "OFF")
1 Like

That is much better. I like consolidation too. :+1:

Where is this explained in the documentation? I am just a little slow wrapping my head around things.

https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Rules.html#function

1 Like

I have not used decorators before in Python. Is i OK to use this thread as I develop my other rules? I am thinking of another case where I think 4 rules could become one.
Basically I am migrating from an M3 Pi system to an M4 VM system with a better Z-Wave controller. I figured I could migrate the rules to Jython & then actually move the Things to minimize service disruption. This rule is just the first piece but I only have 2 main services & a third planned currently.

I don’t have a problem with it. Though there are two schools of thought. One topic per thread makes it easier for others to find. But sometimes seeing a narrative is also useful.

1 Like

Thanks. I asked in another thread how to get & use your Expire library.
With those two I should be able to code rules for an outdoor light / motion sensor only working if it is dark & turning off 5 minutes after last motion detected.

Or you could try this :slight_smile:

I think that is probably overkill right now for me. Thanks for sharing the idea, though.

It would take minutes to copy a few files, customize the configuration, setup your Items and groups, and then you’d be done and all setup to easily add more automations in the future. IMO, building everything from scratch is overkill :roll_eyes:! Let us know how that new wheel rolls!

Right now, I have:

  1. outdoor light & sensor triggered only when Dark & on for 5 minutes after last motion
  2. Basement stairway light with 2 sensors, off 2 minutes after last motion
  3. 3 Plugs (lights) on twice a day based on time & sunrise/sunset.

One thing I will say about Expire with Jython Rules. The benefits of Expire Based Timers pretty much disappear in Python Rules. So if you are mainly using Expire instead of Timers, you will probably be better off going to use Timers instead.

If you have situations where you have one Timer per Item, look at the Timer Manager PR I submitted to the Helper Library as well. It handles managing those for you pretty easily.

It does take a good deal of time and effort to figure out how something like that works. At first glance, I could see how a number of users would say to themselves “I don’t need all that, it’ll be easier to just do it myself.” I see it all the time with even the Rules DSL version of Time of Day.

You and I both know that it’s definitely worth the little bit of effort up front to learn and use libraries like that, but lots of OH users don’t have the benefit of our experience. :wink:

1 Like

I am still taking baby steps here. This is the DSL I am trying to eliminate next with MyTimer being a 5 minute expiry timer.

rule "Papillon Motion On"
when
    Item papillon_motion changed from OFF to ON
then
    if (IsItDark.state == ON) {
        papillon_light.sendCommand(ON)
        // start Timer
        MyTimer.sendCommand(ON)
    }
end

rule "Papillon Motion Off"
when
    Item MyTimer changed from ON to OFF
then
    papillon_light.sendCommand(OFF)
end

I’m just trying to turn you around as you toddle off in a direction that will be more effort :slightly_smiling_face:. The area trigger code handles all of this for you… the timers, mode (ToD) and lux are built in.

For this last one, add the Items to groups and then set some metadata (doesn’t look like you’re using a lux sensor)…

set_metadata("papillon_light", "area_triggers_and_actions", {
    "modes": {
        "Day": {"brightness": 98},
        "Night": {"brightness": 98}
    },
    "actions": {
        "light_action": {"OFF": {"delay": 300}}
    }
}, overwrite=True)

In configuration.mode_dict, use…

mode_dict = OrderedDict([
    ("Day", {"channel": "astro:sun:local:rise#event", "event": "START"}),
    ("Night"  , {"channel": "astro:sun:local:set#event", "event": "START"})
])

I could, but I am using that IsItDark switch.

Which is mode (ToD) functionality

The day & night in the astro binding did not look suitable.
Perhaps I can digest your code later., as I test it.
When I tested your code earlier today, I understood the logic behind it.

That is not what I was referring to. I meant this… https://openhab-scripters.github.io/openhab-helper-libraries/Python/Community/Mode%20(Time%20of%20Day).html, which is used by area triggers.

I’ll tell you what… post your DSL rules and the Items, and I will setup your groups and metadata. It will be useful for others too. Or not… I don’t want to sound pushy… whatever works for you!