Jython: how to compare item states in a *module*?

I can’t figure out how to compare item states e.g. to pre-defined ON or OFF in a Jython module (not script). Essentially, I’d like to define a helper like:

def isON(item_name):
    return scope.itemRegistry.getItem(item_name).state == ON

However, I don’t know how to make the global name ON known here?

Why not compare to a string, “ON” that is. Otherwise you need to import the appropriate classes (and the hassle is to find out which one - it’s in the helper library docs).
Note Python is strict about item types, there’s no implicit conversion like in rules DSL there sometimes is.

1 Like

In the module, do this…

from core.jsr223.scope import ON

You could import the classes instead, but that gets messy.

There is a little more detail here…

Also, there’s no need to get the Item to check its state. All Item states are accessible in items. This is in the default script scope, so also needs importing from core.jsr223.scope when in a module.

from core.jsr223.scope import ON, items
def is_on(item_name):
    return items[item_name] == ON
1 Like

I hesitate to comment too much on this sort of thing but I don’t see any benefit to adding this as a module, as currently written. In a Rule the code to test if a Switch is ON is as simple as

items[item_name] == ON

That is not significantly more complex or more typing than isON(item_name), plus you need to import isON to use it.

However, if you want to make it something more useful, make it also work with DimmerItem and ColorItems too. In that case you could get the Item from the registry and call getStateAs(OnOffType) and if the Item type supports OnOffType it will return it.

1 Like

That was quite helpful, thanks!

I’m having a little trouble with looking up where I’d find the appropriate packages to import - had open the link that you have mentioned, but I can’t seem to find the link between ON and its package core.jsr223.scope from there?

Coming from a Java world (stopped developing 9 years ago), I was already looking for an equivalent of the “Javadocs”, so I can dig into what exists and where to find it. Where would I find something like that?

1 Like

You are right in that

items[item_name] == ON

is not so much more typing work. I prefer it because it keeps the sources a bit more readable for me. I’ve only started to use Jython, so over time, I will probably re-design my helpers quite often. Your “journey” posts are quite helpful for me at the moment - it’s just that my own journey is still ahead, i.e., I’m banging my head against the keyboard over the most basic stuff, from time to time.

Just to highlight what I was aiming at: isON is, of course, a very simplistic helper. I want the look & feel of my code to be consistent, though. What I hated most about Rules DSL is that syntax was obfuscating the meaning.

Therefore, in addition to isON, I’m also defining a bit more unorthodox helper stuff like:

def stateOf(item_name, op, value, unit):
    operators = {
        '>': operator.gt,
        '<': operator.lt,
        '>=': operator.ge,
        '<=': operator.le,
        '=': operator.eq,
        '!=': operator.ne}
    return operators[op](items[item_name], QuantityType(u"{} {}".format(value, unit)))

So my scripts can look like this, e.g.:

def compose_status_report():
    report = []

    if Ephemeris.isBankHoliday:
        report.append(u"🌟 Heute ist ")
        report.append(Ephemeris.getHolidayDescription(Ephemeris.getBankHolidayName()))

    if isOFF("VacationMode"):
        if isON("AssumedFrostToday"):
            pretty_newline(report)
            report.append(u"❄️ VORSICHT GLATTEIS")

            if isDefined("Weather_Temperature"):
                report.append(u"\nDraußen hat es gerade ")
                report.append(u"{}.".format(items["Weather_Temperature"]))

            if isDefined("Weather_Temperature_Min_Today"):
                report.append(u"\nPrognose für heutiges Minimum ist ")
                report.append(u"{}.".format(items["Weather_Temperature_Min_Today"]))

        if isON("AssumedHotToday"):
            pretty_newline(report)
            report.append(u"🌡️ HITZE\nHeute wird es wohl heiss. Morgens die Rolläden in der Küche und im Schlafzimmer herunterlassen?")

        if stateOf("Weather_Windspeed_Max_Today", ">", configuration.MIN_GUSH_SPEED_CONSIDERED_STRONG_IN_KMPH, "km/h"):
            pretty_newline(report)
            report.append(u"🌪️ VORSICHT WINDBÖEN\nHeute wohl Windgeschwindigkeiten bis zu ")
            report.append(u"{}.".format(items["Weather_Windspeed_Max_Today"]))

    return ''.join(report)

I totally understand if this looks like an overkill to you, yet this amount of “readability” is what I wanted to have.

1 Like

I’m not clear on which packages you are referring to. Do you mean Java packages, core helper library modules, ScriptExtensions?

Java packages are mainly in openHAB core (OHC). The Jython core helper libraries have docstrings that are pulled into the documentation. The ScriptExtensions are documented in the official docs. Or is there something else you are looking for?

Those you’ll find in docstrings within the scripts and modules and displayed in the documentation (second link above). If something is unclear, please mention it in the forum, open an issue, or submit a PR (very much appreciated!).

Please don’t hesitate to ask! The more Jython Q&A we get into the forum, the easier the transition will be for everyone. When people are asking questions, it usually means the docs are light in that area, so I try to get most of the answers I give in the forum added to the helper library docs too.

2 Likes

Personally I’m ambivalent about these sorts of efforts. Essentially what you end up creating is your own Rules language. That’s great for you. But it means that any time you want to adopt an example from somewhere else, share your code with someone else, or get help with your code, there will be an additional translation step required.

For example, if you needed help with the above Rule the first thing we would have to ask is "what the heck is isOFF, isDefined, isON?

Obviously do what makes the most sense for you. But I do worry that straying too far from “standard” sets up barriers to your ability to share your code or our ability to help you with problems in your code.

2 Likes

Understand, and appreciate your concerns! You’re right, I want to speed up my development by using, sort of, a “DSL”.

In any case, I consider it my own task to do the “translation work”, in both directions (adopting code of others, and wrapping it, if necessary; as well as asking for advice, providing “plain” code without my “DSL” lingo).

Thanks again for your advice!
Rolf

Thanks a lot!

Yes, the documentation is what I’m struggling with. How can I figure out that

from core.jsr223.scope import ON

is needed to import ON? I feel I must be overlooking something really simple here - starting from the documentation page (which links to core.jsr223), I can’t find a way to spot that ON is in core.jsr223.scope.

Look at the ScriptExtensions link above. core.jsr223.scope will have everything in the default script scope (default preset), including ON.

1 Like